I would like to use $parse in angularJS to dynamically create a scope variable which references an array and then push to that array; but $parse's assign method does not seem to do the trick.
$scope.life.meaning = [];
var the_string = 'life.meaning';
// Get the model
var model = $parse(the_string);
Would like to push '42' into the array. So the following won't work:
// Assigns a value to it
model.assign($scope, 42);
Are there any other ways to do this? Thanks.
Your example is overwriting the assignment for that object on the scope. The $parse can be used to either get or make assignments. What you need to do it get the array and then push the item onto the array that you got. Because JavaScript arrays are pointers in memory, adding to the array that you retrieved will do the trick.
//get the current value as evaluated against the $scope
var ar = $parse('life.meaning')($scope);
//if the value isn't an array then make it one
if (!Array.isArray(ar)) {
ar = [];
$parse('life.meaning').assign($scope, ar);
}
//add an item to the array
ar.push(42);
Related
I never used global variables in Node.js so I have trouble understanding why this wont work. I am declaring global variable that is array, than I want to push some object into it and for sake of debugging I just want to stringify it.
I tried it like this:
var test = require('./api/test'); //my class
global.arrayOfObjects = []; //declaring array
global.arrayOfObjects.push = new test(123); //docs3._id is something I return from db
console.log(JSON.stringify(global.arrayOfObjects)); //I get []
You have to pass the object you want to push into the array as an argument:
global.arrayOfObjects.push(new test(123));
Array.prototype.push() documentation
You must do one of this three, you are mixin both:
var test = require('./api/test');
//global.arrayOfObjects = []; not need to declare the var here
global.arrayOfObjects = new test(123); from db
console.log(JSON.stringify(global.arrayOfObjects));
or
var test = require('./api/test');
global.arrayOfObjects = []; //needed to declare with this option
global.arrayOfObjects.push(1);
global.arrayOfObjects.push(2);
global.arrayOfObjects.push(3);
console.log(JSON.stringify(global.arrayOfObjects));
or
global.arrayOfObjects.push(new test(123)); // I think this is the best option
I have an array of objects (this object also contains an array of it's own) I'm not sure why, but when I push some values onto the member array of one instance of the object in the array of objects it also seems to push onto the other member arrays on all other array of objects. I have provided my code below:
var ImageGroup = {
GroupName:"",
haz:[]
};
var ImageHandler = {
ImageGroupsArray:[],
image_process: function() {
//Calling the function here...
//Pushing the objects
this.ImageGroupsArray.push(Object.create(ImageGroup));
this.ImageGroupsArray.push(Object.create(ImageGroup));
//Assigning some values
this.ImageGroupsArray[0].haz.push("Dog");
this.ImageGroupsArray[1].haz.push("Cat");
//Should output array with only 'Dog' in it
console.log(this.ImageGroupsArray[0].haz);
//Should output array with only 'Cat' in it
console.log(this.ImageGroupsArray[1].haz);
//Instead, both of these output ["Dog","Cat"]
//this.ImageGroupsArray[1].haz and this.ImageGroupsArray[0].haz point to same 'haz' array??
}
}
This doesn't happen when I try to set the GroupName the same way. What am I doing wrong? Thanks for any help in advance!
This code:
var ImageGroup = {
GroupName:"",
haz:[]
};
creates a single object in memory. This code:
this.ImageGroupsArray.push(Object.create(ImageGroup));
this.ImageGroupsArray.push(Object.create(ImageGroup));
creates two new objects (pushing each onto the ImageGroupsArray). Both of these objects have the same ImageGroup object as their prototype. Just knowing how prototypes work will help you a lot on this one. But basically, this code:
this.ImageGroupsArray[0].haz.push("Dog");
this.ImageGroupsArray[1].haz.push("Cat");
looks for the haz property on each of those Object.create()ed objects. When it can't find it, it looks up the prototype chain and finds it on the parent object (which is the same object in both cases). Any modifications made to this one object will, of course, show up in all places where this object is referenced (so in both the objects you pushed to ImageGroupsArray).
The correct approach is to declare ImageGroup as a function that defines its properties:
var ImageGroup = function() {
this.GroupName = '';
this.haz = [];
}
then use the new keyword, instead of Object.create():
this.ImageGroupsArray.push(new ImageGroup());
this.ImageGroupsArray.push(new ImageGroup());
Cheeers.
You are pushing same object ImageGroup in ImageGroupArray and so it is actually making effect in the same object which is defined globally.
Try this instead
function getImageGroup()
{
var imageGroup = new Object();
imageGroup.GroupName = "";
imageGroup.haz = [];
return imageGroup;
}
this.ImageGroupsArray.push(getImageGroup());
this.ImageGroupsArray.push(getImageGroup());
Working Fiddle
It seems you are referencing the same ImageGroup object twice.
The 'groupName' property gets overwritten, but the array can grow endlessly :-)
Try:
var ImageGroup1 = { GroupName:"foo", haz:[]};
var ImageGroup2 = { GroupName:"bar", haz:[]};
So you get two different objects in stead of two references to the same object.
I am in a strange condition. I have an array of objects, I used angular.forEach to modify each object price key value but when I am changing it in each it is also changing main array object as well.
Have a look on code, you will understand then what I am trying to say.
var option_1_val = $scope.options.option_1_val;
var option_2_val = $scope.options.option_2_val;
console.log('genies',sc.genies);
var new_arr = [];
var each ;
each = sc.genies;
angular.forEach(each,function(val,key){
var ob = {};
ob = val;
var priceA = angular.fromJson(ob.price);
console.log('price',priceA);
var option = option_1_val.replace(" ","-")+","+option_2_val.replace(" ","-");
console.log(option);
ob.price = priceA[option];
console.log(ob);
new_arr.push(ob);
});
option = 'Non-Vegetarian,' (after calculating)
sc.genies = [{"gs_id":"3","user_id":"25","service_id":"7","price":"{\"Vegetarian,Bengali\":\"200\",\"Vegetarian
,Chinese\":\"3100\",\"Vegetarian,Gujarati\":\"800\",\"Vegetarian,Italian\":\"100\",\"Vegetarian,Maharashtrian
\":\"100\",\"Vegetarian,Punjabi\":\"100\",\"Vegetarian,-South-Indian\":\"300\",\"Vegetarian,Thai\":\"100
\",\"Non-Vegetarian,Bengali\":\"1100\",\"Non-Vegetarian,Chinese\":\"3100\",\"Non-Vegetarian,Gujarati
\":\"100\",\"Non-Vegetarian,Italian\":\"100\",\"Non-Vegetarian,Maharashtrian\":\"100\",\"Non-Vegetarian
,Punjabi\":\"100\",\"Non-Vegetarian,-South-Indian\":\"80\",\"Non-Vegetarian,Thai\":\"100\",\"Jain,Bengali
\":\"2100\",\"Jain,Chinese\":\"2100\",\"Jain,Gujarati\":\"4100\",\"Jain,Italian\":\"100\",\"Jain,Maharashtrian
\":\"100\",\"Jain,Punjabi\":\"100\",\"Jain,-South-Indian\":\"800\",\"Jain,Thai\":\"100\"}","min_price"
:"80","max_price":"4100","username":"abdul quadir","email":"abdul.quadir#kiozen.com","rating":"3"}]
now when I am repeating sc.genie, I have taken it in a new variable already "each" and then I am changing "price" key of each array to undefined but strange point is when I see in console value of price in sc.genies is also changed to "undefined". Huh!
I hope you got my point, please help me why is that happening.
Thanks
You should use angular.copy then when change in each value not affect to original value. because of angular.copy assign old value in new variable without reference.
like:
var each ;
each = angular.copy(sc.genies);
instead of
each = sc.genies;
There is a simple answer. The reason why "both" values changes, is because it is actually the same object. The variable val from this line angular.forEach(each,function(val,key){ ... contains a pointer to an object. It is not another object. It is the same object, it is only accessed via different variable name.
If you really want the original and working copy to be different objects, then you need to manually create new instance with the same values.
You can create copy of an object like this (good for simple objects):
var copy = JSON.parse(JSON.stringify(originalObject));
or as pointed in the comment above, you can use angular.copy(source, destination). See the documentation https://docs.angularjs.org/api/ng/function/angular.copy
Newbie here...be nice.
I have an empty object that will get pushed into an array.
listView = {};
I add properties to it.
listView.code = code;
listView.description = description;
I push the results object into an array.
listy.push(listView);
Each time I enter a new selection in step #2 it overwrites the object instead of adding the new object properties to the array. It also increments the index by one, so it just repeats...
[{"code":"I77.812","description":"Thoracoabdominal Aortic Ectasia"}]
[{"code":"I77.811","description":"Abdominal Aortic Ectasia"},{"code":"I77.811","description":"Abdominal Aortic Ectasia"}]
[{"code":"I06.1","description":"Rheumatic aortic insufficiency"},{"code":"I06.1","description":"Rheumatic aortic insufficiency"},{"code":"I06.1","description":"Rheumatic aortic insufficiency"}]
The array should contain three different objects. But instead it has three copies of the newly added one...
How should I be adding the new choice objects so that they don't get overwritten?
You are always adding a reference to the same object, and changing that same object, instead of adding new objects. See this:
var a = [];
var o = {};
for (var i = 0; i < 5; i++) {
o.id = i;
a.push(o);
}
a
// => [{"id":4},{"id":4},{"id":4},{"id":4},{"id":4}]
But
var a = [];
for (var i = 0; i < 5; i++) {
var o = {};
o.id = i;
a.push(o);
}
a
// => [{"id":0},{"id":1},{"id":2},{"id":3},{"id":4}]
The difference is, the second code always makes a new object that is distinct from all other objects already in the array.
As a metaphor, imagine a theatre director in casting. He turns to an actor, says "You... you'll be Romeo.". Then he looks at the same actor, says "You... you'll be Mercutio. Here, Mercutio, take this sword. Romeo... who told you to get a sword?!?" completely failing to realise that, if Romeo and Mercutio are the same person, if one of them picks up a sword, the other does it too.
Seeing as you declared yourself a 'newbie' i figured i'd take a bit more time explaining. When you push an object to an array, you don't copy the object. You just tell the array where to find the object (a reference). If you push the same object 3 times, the array just has 3 indexes at which it finds the same object. There's several ways around this, the easiest being that you declare the variable inside the loop
for (var i=0;i<3;i++){
var listView = {};
listView.id = i;
listy.push(listView);
}
This way listView is a different reference each time. The other way is to create a new object when you push
listy.push({id:listView.id, description:listView.description});
which works because simple variables are 'copied' into the array and not referenced.
your assignment of the properties of an object are simply replacing the existing properties. wh en you push the object in the array by name, you are push a reference to the object and not a value. This is why all the elements in the array are the same. You need to create a new object every time you push. Something like this should work for you.
listy.push({code:code, description:description});
try this :
listy.push({
code:listView.code,
description : listView.description
})
In my code I have used pass by value.
In your code , you are using Objects which are passed by reference .
You are adding same reference again and again so at the end you will get an array having all the values of same object .
To understand more about pass by value and pass by reference you can reffer this link :
Pass Variables by Reference in Javascript
I have found a behavior I did not expect when trying to use a loop in order to change the value set for a property in an object.
Basically, I declare my object outside the loop.
Then I loop on an array of numeric values, which values are used to update the object property.
Inside the loop, I store the current object state inside an external array.
The result is that instead of having an array containing a series of objects with different numeric values, I end up having the same numeric values in each object stored.
Here is the fiddle http://jsfiddle.net/fAypL/1/
jQuery(function(){
var object_container = [];
var numeric_values = [1, 2 , 3, 4];
var my_object = {};
jQuery.each(numeric_values, function(index, value){
my_object['value'] = value;
object_container.push(my_object);
});
jQuery.each(object_container, function(index, value){
jQuery('#content').prepend(value['value']);
});
});
I would expect to get 1 2 3 4 as values stored in each object, however, what I get is 4 4 4 4, which does not make sense to me.
Any hint on this behavior is more than welcome, thanks
When your code calls .push() and passes my_object, what's being passed is a reference to the object. No copy is made.
Thus, you've pushed four references to the exact same object into the array.
JavaScript objects always participate in expressions in the form of references. There's no other way to deal with objects. Thus when you create a variable, and set its value to be an object, you're really setting its value to be a reference to the object. Same with parameter passing, and anywhere else an object can appear in an expression.
In this case, you can create new objects pretty easily; just dispense with my_object and push a fresh one on each iteration:
object_container.push( { value: value } );
You are not creating a new object each time around the loop - you are just updating the same existing object and pushing references of that to the object array. To create a new object you want to do something like:
my_object = { 'value': value };
object_container.push(my_object);
In this case you now will get something more like what you were looking for. See the updated fiddle here: http://jsfiddle.net/fAypL/2/.
Best of luck!
One more thought (Clone!) - If you are really tied to using the same object each time, just clone the object before you add to the array. There is a great solution for that here.
You are using jQuery so if what you want is to merge without effecting the original look at :
var both_obj = $.extend( {}, default_obj , adding_obj );
This will leave your original object changed, also good to use for a copy.
jquery docs - extend()
An alternate version is to use an object with a constructor and the new keyword:
var object_container = [];
var numeric_values = [1, 2 , 3, 4];
function MyObject(value)
{
this.value = value;
}
jQuery.each(numeric_values, function(index, value){
object_container.push(new MyObject(value));
});
jQuery.each(object_container, function(index, value){
jQuery('#content').prepend(value['value']);
});
Fiddle