Reputation: 5151
Below is my code to change an object inside an array into a string. Can't figure out why it effects the original array. slice is supposed to clone array, if I am right?
var cloned = $scope.selected.items.slice(0);
cloned.forEach(function (cluster) {
cluster.status = cluster.status.name;
})
ObjToPost.MO = cloned;
console.log("consoling the cluster list", ObjToPost.MO);
console.log("consoling the original cluster list", $scope.selected.items);
After consoling both the arrays are same
Upvotes: 3
Views: 97
Reputation: 191976
As @thefourtheye explained, you are creating a shallow copy of the array. To deep copy the array items, and modify the status, you can use Array.prototype.map with angular.merge():
ObjToPost.MO = $scope.selected.items.map(function(cluster) {
return angular.merge({}, cluster, { status: cluster.status.name }); // create a deep copy of each item, and override status with status.name
});
Upvotes: 0
Reputation: 239473
Quoting MDN on Array.prototype.slice
,
The
slice()
method returns a shallow copy of a portion of an array into a new array object.
The important words here are "shallow copy". It creates a new Array and makes the elements of the array point to the same object.
In your case, even after slicing, each of the array elements in both the original and cloned arrays refer the same cluster objects in memory.
Original Cloned
+-----+ +-----+
| 0 |--> Cluster Object 1 <--| 0 |
+-----+ +-----+
| 1 |--> Cluster Object 2 <--| 1 |
+-----+ +-----+
| 2 |--> Cluster Object 3 <--| 2 |
+-----+ +-----+
Since all the corresponding elements are referring to the same objects, changing it through one array will be reflected in the other as well.
Note: If you are looking for a way to do deep copy, then you might want to check this question.
Upvotes: 7