51

I wonder if there is away to avoid copying references to objects when you need to create a simple object which has an array of embedded objects.The situation is as follow: I have server which accepts a JSON and applies some logic then stores the object in DB. lets say my form is for saving teams in DB. The server accepts team as json. the team has an array of TeamMember objects, my form has a simple field to enter team member info and add it to team teamMembers array. Now here is the problem, when I add a team member to array list and want to add another team member when I type into the field the added member is changed also !. I know the reason

$scope.addTeamMember=function(teamMember){
   $scope.team.teamMembers.push(teamMember);
}

and it is because I put same reference into the teamMembers array so I have same object added several times. to avoid this I should create a new team member object, copy all teamMember properties and and add it the array.

 $scope.addTeamMember=function(teamMember){
       var newTeamMember; /*<--- copy teamMember */
       $scope.team.teamMembers.push(newTeamMember); /*and add newTeamMember*/
    }
Matt DeKrey
  • 11,582
  • 5
  • 54
  • 69
Adelin
  • 18,144
  • 26
  • 115
  • 175

3 Answers3

116

Your question says you want to "avoid deep copy", but I'm not sure that's accurate. It sounds like you just want to use angular.copy, because you need to create a copy of the team member and add that to the array:

$scope.addTeamMember = function(teamMember) {
   var newTeamMember = angular.copy(teamMember);
   $scope.team.teamMembers.push(newTeamMember);
};
Ben Lesh
  • 107,825
  • 47
  • 247
  • 232
  • 1
    why not just push the teamMember ? why make a copy – landed Jun 25 '15 at 08:35
  • 12
    Since JavaScript objects are passed by reference, if one pushed the teamMember to the array and eventually modified it then the original object would be modified as well. `var animal = {Name: 'dog'};` then we add it to an array twice. `var array = [ ]; array.push(animal); array.push(animal);` then we modified the second animal within the array. `array[1].Name = 'cat';` Now, all of the animals are named `cat`. `console.log(animal.Name); console.log(array[0];` Output: 'cat' for both. – Levi Fuller Jul 13 '15 at 22:29
6

This is the best documentation available

https://docs.angularjs.org/api/ng/function/angular.copy

there is a live example as well on the page which is self illustrative.

anandharshan
  • 5,817
  • 4
  • 34
  • 33
0

I personally use this:

    function copyObjToObj(source, destination) {
        if(!angular.equals(source,destination)){
            if (!!destination) 
                angular.copy(source, destination);
            else 
                destination = angular.copy(source);
        }
        return destination;
    }
var destination = copyObjToObj(sourceObj, destination);
Noman Chali
  • 330
  • 3
  • 15