$watch an object

Vladimir Sidorenko picture Vladimir Sidorenko · Oct 18, 2013 · Viewed 165k times · Source

I want to watch for changes in a dictionary, but for some reason watch callback is not called.

Here is a controller that I use:

function MyController($scope) {
    $scope.form = {
        name: 'my name',
        surname: 'surname'
    }

    $scope.$watch('form', function(newVal, oldVal){
        console.log('changed');
    });
}

Here is fiddle.

I expect $watch callback to be fired each time name or surname is changed, but it doesn't happen.

What is the correct way to do it?

Answer

rossipedia picture rossipedia · Oct 18, 2013

Call $watch with true as the third argument:

$scope.$watch('form', function(newVal, oldVal){
    console.log('changed');
}, true);

By default when comparing two complex objects in JavaScript, they will be checked for "reference" equality, which asks if the two objects refer to the same thing, rather than "value" equality, which checks if the values of all the properties of those objects are equal.

Per the Angular documentation, the third parameter is for objectEquality:

When objectEquality == true, inequality of the watchExpression is determined according to the angular.equals function. To save the value of the object for later comparison, the angular.copy function is used. This therefore means that watching complex objects will have adverse memory and performance implications.