How to deep watch an array in angularjs?
There are performance consequences to deep-diving an object in your $watch. Sometimes (for example, when changes are only pushes and pops), you might want to $watch an easily calculated value, such as array.length.
If you're going to watch only one array, you can simply use this bit of code:
$scope.$watch('columns', function() {
// some value in the array has changed
}, true); // watching properties
example
But this will not work with multiple arrays:
$scope.$watch('columns + ANOTHER_ARRAY', function() {
// will never be called when things change in columns or ANOTHER_ARRAY
}, true);
example
To handle this situation, I usually convert the multiple arrays I want to watch into JSON:
$scope.$watch(function() {
return angular.toJson([$scope.columns, $scope.ANOTHER_ARRAY, ... ]);
},
function() {
// some value in some array has changed
}
example
As @jssebastian pointed out in the comments, JSON.stringify
may be preferable to angular.toJson
as it can handle members that start with '$' and possible other cases as well.
You can set the 3rd argument of $watch
to true
:
$scope.$watch('data', function (newVal, oldVal) { /*...*/ }, true);
See https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watch
Since Angular 1.1.x you can also use $watchCollection to watch shallow watch (just the "first level" of) the collection.
$scope.$watchCollection('data', function (newVal, oldVal) { /*...*/ });
See https://docs.angularjs.org/api/ng/type/$rootScope.Scope#$watchCollection