Saiful Azad
Saiful Azad

Reputation: 1921

AngularJS facing trouble to understand clone object and reference assignment

I am facing problem in AngularJS 1.6 There are some confusions. I am iterating an array of objects named aList which contains mutable objects in HTML part.

<div ng-repeat="item in aList>
   <a ng-click = "updateDataFun(item)">Click</a>
</div>

Now in controller I have this

constructor(){
    this.updateData = {};
}
updateDataFun(item){
   // this.updateData = Object.assign({}, item); // this solve the issue. 
   this.updateData = item; 
}
cancelUpdate(){
   this.updateData = {}
}

Now, on a modal, I have something like that <input ng-model="updateData.name">

If I change anything (name, an attribute of updateData) via modal and press cancelUpdate() the changes reflect to aList array.

Here are some questions:

  1. At updateDataFun(item) method, the assignment is reference assignment (assume). Am I right? So that, if I change on this.updateData via modal, it reflects item. Also, change aList index value where the item associated to.
  2. If so then on cancelUpdate() invocation, this.updateData will be {}. Why does this not reflect item? It should be {}.

However, if I uncomment this.updateData = Object.assign({}, item); and comment this.updateData = item; then it is working.

Upvotes: 2

Views: 117

Answers (2)

yaron
yaron

Reputation: 41

javascript passing object by reference and not by value so this line is your issue:

this.updateData = item; 

this line pass the item by reference so all the changes you will be make for this variable will be affect the source list item. suggested solution is to copy the object instead of pass it by reference like this :

this.updateData = JSON.parse(JSON.stringify(item)); // create new item in the memory and assign it to updateData variable 

you can use any other cloning method you want or create new object with only the values you need

Edit sorry missing your questions,

  1. you right as explained before,
  2. when you write

    variable = {} the meaning is that your not changing the reference of variable to empty object, you assign new (and empty) object to the variable (and not to the reference of the object)

hopes its help

Upvotes: 2

Mike Drakoulelis
Mike Drakoulelis

Reputation: 789

As suggested by yaron, your assumption that this.updateData has a reference to the individual item from aList is correct. Thus, when you change a property of this.updateData anywhere (even in a modal, if the modal receives a reference as well), it is reflected to the list.

However, in cancelUpdate() you assign an empty object in place of that reference (you replace the item reference with a reference to something else). The reference to item is broken thus any change from that time on (including the assigning of an empty object) is not reflected. If you want to assign {} to item you have to update the list directly or mutate the item object directly (not reassign).

this.updateData = Object.assign({}, item) clones the item to a brand new object and stores its reference to this.updateData thus any changes will again not be reflected to item.

Upvotes: 1

Related Questions