The angular. copy function takes an object, array or a value and creates a deep copy of it.
A shallow copy looks like the original, but if the original includes composites (complex objects, arrays, etc.) then those objects get included in the copy by reference. That means if you make changes to the original object, those changes get reflected in the cloned object. But again: that's only for composites.
shallow copying. A deep copy means that all of the values of the new variable are copied and disconnected from the original variable. A shallow copy means that certain (sub-)values are still connected to the original variable.
So when the copy is mutated, the original also gets mutated. This is also known as shallow copying. If we instead want to copy an object so that we can modify it without affecting the original object, we need to make a deep copy.
Use angular.copy when assigning value of object or array to another variable and that object
value should not be changed.
Without deep copy or using angular.copy, changing value of property or adding any new property update all object referencing that same object.
var app = angular.module('copyExample', []);
app.controller('ExampleController', ['$scope',
function($scope) {
$scope.printToConsole = function() {
$scope.main = {
first: 'first',
second: 'second'
};
$scope.child = angular.copy($scope.main);
console.log('Main object :');
console.log($scope.main);
console.log('Child object with angular.copy :');
console.log($scope.child);
$scope.child.first = 'last';
console.log('New Child object :')
console.log($scope.child);
console.log('Main object after child change and using angular.copy :');
console.log($scope.main);
console.log('Assing main object without copy and updating child');
$scope.child = $scope.main;
$scope.child.first = 'last';
console.log('Main object after update:');
console.log($scope.main);
console.log('Child object after update:');
console.log($scope.child);
}
}
]);
// Basic object assigning example
var main = {
first: 'first',
second: 'second'
};
var one = main; // same as main
var two = main; // same as main
console.log('main :' + JSON.stringify(main)); // All object are same
console.log('one :' + JSON.stringify(one)); // All object are same
console.log('two :' + JSON.stringify(two)); // All object are same
two = {
three: 'three'
}; // two changed but one and main remains same
console.log('main :' + JSON.stringify(main)); // one and main are same
console.log('one :' + JSON.stringify(one)); // one and main are same
console.log('two :' + JSON.stringify(two)); // two is changed
two = main; // same as main
two.first = 'last'; // change value of object's property so changed value of all object property
console.log('main :' + JSON.stringify(main)); // All object are same with new value
console.log('one :' + JSON.stringify(one)); // All object are same with new value
console.log('two :' + JSON.stringify(two)); // All object are same with new value
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="copyExample" ng-controller="ExampleController">
<button ng-click='printToConsole()'>Explain</button>
</div>
In that case, you don't need to use angular.copy()
Explanation :
=
represents a reference whereas angular.copy()
creates a new object as a deep copy.
Using =
would mean that changing a property of response.data
would change the corresponding property of $scope.example
or vice versa.
Using angular.copy()
the two objects would remain seperate and changes would not reflect on each other.
I would say angular.copy(source);
in your situation is unnecessary if later on you do not use is it without a destination angular.copy(source, [destination]);
.
If a destination is provided, all of its elements (for arrays) or properties (for objects) are deleted and then all elements/properties from the source are copied to it.
https://docs.angularjs.org/api/ng/function/angular.copy
When using angular.copy, instead of updating the reference, a new object is created and assigned to the destination(if a destination is provided). But there's more. There's this cool thing that happens after a deep copy.
Say you have a factory service which has methods which updates factory variables.
angular.module('test').factory('TestService', [function () {
var o = {
shallow: [0,1], // initial value(for demonstration)
deep: [0,2] // initial value(for demonstration)
};
o.shallowCopy = function () {
o.shallow = [1,2,3]
}
o.deepCopy = function () {
angular.copy([4,5,6], o.deep);
}
return o;
}]);
and a controller which uses this service,
angular.module('test').controller('Ctrl', ['TestService', function (TestService) {
var shallow = TestService.shallow;
var deep = TestService.deep;
console.log('****Printing initial values');
console.log(shallow);
console.log(deep);
TestService.shallowCopy();
TestService.deepCopy();
console.log('****Printing values after service method execution');
console.log(shallow);
console.log(deep);
console.log('****Printing service variables directly');
console.log(TestService.shallow);
console.log(TestService.deep);
}]);
When the above program is run the output will be as follows,
****Printing initial values
[0,1]
[0,2]
****Printing values after service method execution
[0,1]
[4,5,6]
****Printing service variables directly
[1,2,3]
[4,5,6]
Thus the cool thing about using angular copy is that, the references of the destination are reflected with the change of values, without having to re-assign the values manually, again.
I know its already answered, still i am just trying to make it simple. So angular.copy(data) you can use in case where you want to modify/change your received object by keeping its original values unmodified/unchanged.
For example: suppose i have made api call and got my originalObj, now i want to change the values of api originalObj for some case but i want the original values too so what i can do is, i can make a copy of my api originalObj in duplicateObj and modify duplicateObj this way my originalObj values will not change. In simple words duplicateObj modification will not reflect in originalObj unlike how js obj behave.
$scope.originalObj={
fname:'sudarshan',
country:'India'
}
$scope.duplicateObj=angular.copy($scope.originalObj);
console.log('----------originalObj--------------');
console.log($scope.originalObj);
console.log('-----------duplicateObj---------------');
console.log($scope.duplicateObj);
$scope.duplicateObj.fname='SUD';
$scope.duplicateObj.country='USA';
console.log('---------After update-------')
console.log('----------originalObj--------------');
console.log($scope.originalObj);
console.log('-----------duplicateObj---------------');
console.log($scope.duplicateObj);
Result is like....
----------originalObj--------------
manageProfileController.js:1183 {fname: "sudarshan", country: "India"}
manageProfileController.js:1184 -----------duplicateObj---------------
manageProfileController.js:1185 {fname: "sudarshan", country: "India"}
manageProfileController.js:1189 ---------After update-------
manageProfileController.js:1190 ----------originalObj--------------
manageProfileController.js:1191 {fname: "sudarshan", country: "India"}
manageProfileController.js:1192 -----------duplicateObj---------------
manageProfileController.js:1193 {fname: "SUD", country: "USA"}
I am just sharing my experience here, I used angular.copy() for comparing two objects properties. I was working on a number of inputs without form element, I was wondering how to compare two objects properties and based on result I have to enable and disable the save button. So I used as below.
I assigned an original server object user values to my dummy object to say userCopy and used watch to check changes to the user object.
My server API which gets me data from the server:
var req = {
method: 'GET',
url: 'user/profile/' + id,
headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}
$http(req).success(function(data) {
$scope.user = data;
$scope.userCopy = angular.copy($scope.user);
$scope.btnSts=true;
}).error(function(data) {
$ionicLoading.hide();
});
//initially my save button is disabled because objects are same, once something
//changes I am activating save button
$scope.btnSts = true;
$scope.$watch('user', function(newVal, oldVal) {
console.log($scope.userCopy.name);
if ($scope.userCopy.name !== $scope.user.name || $scope.userCopy.email !== $scope.user.email) {
console.log('Changed');
$scope.btnSts = false;
} else {
console.log('Unchanged');
$scope.btnSts = true;
}
}, true);
I am not sure but comparing two objects was really headache for me always but with angular.copy() it went smoothly.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With