Bernardo Loureiro
Bernardo Loureiro

Reputation: 453

AngularJS is cross-binding variables?

I begin my Angular controller by downloading JSON data using Promises and storing it in variables:

app.controller('mainController', ['$scope', '$http', '$q', function($scope, $http, $q) {
  var req1 = $http({method: 'GET', url: 'link to JSON 1', cache: 'true'});
  var req2 = $http({method: 'GET', url: 'link to JSON 2', cache: 'true'});

  $q.all([req1, req2]).then(function(response){
    var res1 = response[0].data;
    var res2 = response[1].data;

    $scope.data1 = res1;       // JSON which I will manipulate
    $scope.data1Ref = res1;   // JSON for reference which I won't manipulate

    $scope.data2 = res2;
    $scope.data2Ref = res2;

    init(); // do the stuff with the data
  });
}]);

After init() is done however, if I check $scope.data1 and $scope.data1Ref they both have been modified, that is they're bound together.

Why is this happening and how can I make sure to keep a stored version of the original downloaded JSON for reference?

Upvotes: 0

Views: 152

Answers (3)

dhemz
dhemz

Reputation: 26

In AngularJS, complex objects are passed by reference. You can find more info here: Difference between angular.copy() and assignment (=)

Upvotes: 0

paulgoblin
paulgoblin

Reputation: 157

This is because in JavaScript, objects are passed by reference. When you set $scope.data1 and $scope.data1Ref equal to res1, you are setting them equal to a reference to res1.

To get around this, you can make a deep copy of your res objects using angular.copy.

$scope.res1Ref = angular.copy(res1);

Upvotes: 0

Ben Jaspers
Ben Jaspers

Reputation: 1546

When you use assignment for objects, you are only giving the variable a reference to the object, not copying the object. In your code, $scope.data1, $scope.data1Ref, and res1 are all pointing to the exact same object instance. To make a new object you need to copy the existing object.

Angular provides two functions which can copy an object, one creates a shallow copy, and the other a deep copy. A shallow copy copies primitive fields and if the object contains child objects, then the original and the copy both point to the same child object instance. In a deep copy, any child objects have new copies created also.

angular.extend can be used to create a shallow copy, while angular.copy does a deep copy.

Upvotes: 0

Related Questions