How to remove the angular scope array values using key name? - arrays

I have an angular scope array now i want to remove one item from that array using key name for example i want to remove DataTypeName from that array.
$scope.attributes = [
{DataTypeName: "Text"
objectAttributeDataTypeId: "3654B05F-E09E-49A9-8E5F-0FC623BBE009"
objectAttributeId: "9df52354-67dd-453a-87fd-abb38b448db9"
objectAttributeLabelName: "test"
objectAttributeName: "test"}]
Please anyone help me to remove the array.

seems like you need to remove the objectAttributeDataTypeId from the first element of the array which is a object.
so what you need is,
$scope.attributes[0] // get the first element of the array
$scope.attributes[0].DataTypeName // get the DataTypeName attribute of the object
delete $scope.attributes[0].DataTypeName; // delete the property.
so all you need is,
delete $scope.attributes[0].DataTypeName;

If you want to filter array you can use native Array.prototype.filter method for this:
$scope = {}; // stub $scope for demo
$scope.attributes = [
{
DataTypeName: "Text",
objectAttributeDataTypeId: "3654B05F-E09E-49A9-8E5F-0FC623BBE009",
objectAttributeId: "9df52354-67dd-453a-87fd-abb38b448db9",
objectAttributeLabelName: "test",
objectAttributeName: "test"
},
{
DataTypeName: "Image",
objectAttributeDataTypeId: "3654B05F-E09E-49A9-8E5F-0FC623BBE009",
objectAttributeId: "9df52354-67dd-453a-87fd-abb38b448db9",
objectAttributeLabelName: "test",
objectAttributeName: "test"
}
];
// Filter out only "Text" types
$scope.filtered = $scope.attributes.filter(function(attr) {
return attr.DataTypeName == "Text";
});
document.write('<pre>' + JSON.stringify($scope.filtered, null, 4));

Related

How to update to an array if element already exists

I'm making a React-Native application. Thanks to everyone's help I could somehow make that work except for toggling YES and NO. Once the user clicks on a button I just want to check if that clicked item data already exists in the state, if so I want to update it. If it does not exist then it should be added to the state as a new Item.
I already coded the above logic, my code is working, but not returning correct output, elements are not adding or updating to the state array properly. How do I fix this code?
I want to generate output like this
[{
chelistid:231,
validiary : "YES",
remark : "Hello"
},{
chelistid:232,
validiary : "NO",
remark : "asddddd"
}]
My code
const [reqData, setReqData] = useState([]);
//Modify yes clicked
const yesClicked = (element) => {
let req = {
"chelistid": element.chelistid,
"validiary": "Yes",
"remark": element.remark
}
createCheckList(req);
}
//Modify no clicked
const noClicked = (element) => {
let req = {
"chelistid": element.chelistid,
"validiary": "No",
"remark": element.remark
}
createCheckList(req);
}
const createCheckList = (data) => {
const index = reqData.findIndex(x => x.chelistid === data.chelistid)
var modifiedArray = reqData
if (index !== -1) {
//Remove the element from the array
modifiedArray.splice(index, 1);
}
setReqData([modifiedArray, data]);
}
The problem is it seems like you are not spreading the array to append the data element. What you are doing by [modifiedArray, data] you are creating an array that contains an array and data something like [[modified array content here], data]. But actually, you want to append to modified array instead. For that, you need to expand the modified array by using ... which is called spread syntax. (Learn here) So, your code would look like:
setReqData([...modifiedArray, data]);

Array as Model for Service Breaks when Empty

I have two routes: one has a custom component that repeats the data in an array and allows the user to add and remove items, the other route only displays the model. The model is stored in a service. The model JSON data looks like this:
[
{name: "one"},
{name: "two"},
{name: "three"}
]
The components are all using ng-model and assigning this to a variable vm. Following all the best practices from John Papa style guide.
If I empty the array either by using slice(), pop(), or setting the array length to 0, it breaks. You can still add data to it, but if you navigate to the other route, the model will show as an empty array. And if you navigate back again, the array is still empty.
If I make my model an object with a key and the array as the value, everything works as expected. So my question is, is this just a limitation or am I doing something wrong?
{
myarray: [
{name: "one"},
{name: "two"},
{name: "three"}
]
}
Here is the working example using the object containing the array.
And here is the non working example just using the array.
You'll see on the one that does not work, you'll empty the array and then add to it, it will not persist data across the routes.
you'll empty the array and then add to it, it will not persist data across the routes
1st Problem: in getAsync() method.
When your model is empty you call callAtInterval() every 100 milliseconds and you never resolve your promise (infinite loop).
function getAsync() {
function callAtInterval() {
if (!_.isEmpty(genericHttpModel.model)){
$interval.cancel(promise);
deferred.resolve(get());
}
}
var deferred = $q.defer();
var promise = $interval(callAtInterval, 100);
return deferred.promise;
}
Therefore when user goes to home (root) route:
genericHttpService.getAsync().then(function(model){
vm.model = model; // <-- never called
});
So remove if (!_.isEmpty(genericHttpModel.model)) statement
function callAtInterval() {
$interval.cancel(promise);
deferred.resolve(get());
}
}
2nd problem: in add method:
function add() {
if (modelEmpty()) {
initModelAndAddOne();
} else {
vm.model.push({});
}
}
In initModelAndAddOne you reset original instance of vm.model with:
vm.model = [];
Your model is already empty, why to redefine it with =[], make it simple:
function add() {
vm.model.push({});
}
Working Example Plunker
working example using the object containing the array.
So why it works:
1st off _.isEmpty(genericHttpModel.model) will always return false because object contains field names a.e: genericHttpModel.model = {names:[]}
2nd - vm.model = [] resets names field only and not service object

How to filter a multidimentional JSON Object

I have a Json string which contains many json objects, each json has a key, I use JSON.parse to place the string into an object.
I then extract what I need in the following format
json['product1'][0].name
However, I want to get an array of element from each of the json objects based on the value of another elements. Currently I am using:
for each (var row:Object in json) {
if (row[0][filterElement] == filterValue) {
arr.push(row[0][element]);
}
}
Is this a good approach? I ask because it seems that I am going through the entire json object every time.
If I've understood your question correctly, it sounds like you want to use .map and .filter.
So if we have an object such as...
var obj = {
people: [
{name: 'person1'},
{name: 'person2'},
{name: 'person3'},
{name: 'person4'},
]
};
You can then use .map to create a new array of names...
var names = obj.people.map(function(person){
return person.name;
}); // ['person1', 'person2', 'person3', 'person4']
on this array you can then use .filter...
var filter = 'person2';
var filteredNames = obj.people.map(function(person){
return person.name;
}).filter(function(name){
return name == filter; // if true, will push name into a name into our new array
}); // 'person2'
This is obviously a rudimentary example, but the same concepts will apply for the precise properties which apply in your question. Hope this helps.

add a element to json array with Key/value using angular js

I have a json array object like below
$scope.Json = [{
Id:"5464",
Class:"9",
Rank:"4"
}]
I want to add a item "Name":"Vicky" to the Json. So that my result should be as below.
$scope.Json = [{
Id:"5464",
Class:"9",
Rank:"4",
Name:"Vicky"
}]
I am new to angular, can anyone help on this?
Use Array map() method.
DEMO
var json = [{ Id:"5464", Class:"9", Rank:"4" }];
json.map(function(item) {
item.Name = 'Vicky';
});
console.log(json);
First of all, the object $scope.Json is not a JSON but a string. To get a JSON, you need to parse the string like the following:
$scope.Json = JSON.parse(<string>) ;
Second, your input is a peculiar JSON as it is an array with one element (in its turn having 3 elements. I guess you wanted this:
$scope.Json = JSON.parse({ Id:"5464", Class:"9", Rank:"4" }) ;
Once you have this, you can add the element you want as:
$scope.Json.Name = "Vicky" ;

How can I set nested array values in meteor publish function?

I have two collection "contents" and "units". In the content collection is a field "unitID" which refers to the unit-collection. In the meteor publish function I want to add the unit type name of all new created contents:
Meteor.publish("contents", function () {
var self = this;
var handle = Contents.find().observe({
changed: function(contentdoc, contentid) {
var UnitName = Units.findOne({_id: contentdoc.unittypeid }, {fields: {type: 1}});
self.set("contents", contentid, {'content.0.typename': UnitName});
self.flush();
}
});
}
This works but it creates a new attribut "content.0.UnitName" instead of inserting the attribute "UnitName" in the first element of the content array:
[
{
_id:"50bba3ca8f3d1db27f000021",
'content.0.UnitName':
{
_id:"509ff643f3a6690c9ca5ee59",
type:"Drawer small"
},
content:
[
{
unitID:"509ff643f3a6690c9ca5ee59",
name: 'Content1'
}
]
}
]
What I want is the following:
[
{
_id:"50bba3ca8f3d1db27f000021",
content:
[
{
unitID:"509ff643f3a6690c9ca5ee59",
name: 'Content1',
UnitName:
{
_id:"509ff643f3a6690c9ca5ee59",
type:"Drawer small"
}
}
]
}
]
What am I doing wrong?
this.set within Meteor.publish only works on the top-level properties of an object, meaning it doesn't support Mongo-style dotted attributes. You'll have to call set with the entire new value of the contents array.
Caveat: What I am about to say is going to change in a future release of Meteor. We're currently overhauling the custom publisher API to make it easier to use, but in a way that breaks back-compatibility.
That said...
It looks like what you're trying to do is build a server-side join into the published collection "contents". Here, for reference, is the current code (as of 0.5.2) that publishes a cursor (for when your publisher returns a cursor object):
Cursor.prototype._publishCursor = function (sub) {
var self = this;
var collection = self._cursorDescription.collectionName;
var observeHandle = self._observeUnordered({
added: function (obj) {
sub.set(collection, obj._id, obj);
sub.flush();
},
changed: function (obj, oldObj) {
var set = {};
_.each(obj, function (v, k) {
if (!_.isEqual(v, oldObj[k]))
set[k] = v;
});
sub.set(collection, obj._id, set);
var deadKeys = _.difference(_.keys(oldObj), _.keys(obj));
sub.unset(collection, obj._id, deadKeys);
sub.flush();
},
removed: function (oldObj) {
sub.unset(collection, oldObj._id, _.keys(oldObj));
sub.flush();
}
});
// _observeUnordered only returns after the initial added callbacks have run.
// mark subscription as completed.
sub.complete();
sub.flush();
// register stop callback (expects lambda w/ no args).
sub.onStop(function () {observeHandle.stop();});
};
To build a custom publisher that is joined with another table, modify the added callback to:
check if the added object has the key you want to join by
do a find in the other collection for that key
call set on your subscription with the new key and value you want to be published, before you call flush.
Note that the above is only sufficient if you know the key you want will always be in the other table, and that it never changes. If it might change, you'll have to set up an observe on the second table too, and re-set the key on the sub in the changed method there.

Resources