Question

I'm trying to build a real watcher for a collection in my app and, at first, I thought that Angular would provide me everything I needed.

I mean, I had the $watch, both shallow and deep. and the $watchCollection, a $digest cycle that loops over my $scope-exposed variables through the dirty checking mechanic and triggers all the watchers...

Great! What else could I need?

Wrong!

Turns out that $watchCollection gets triggered only at the first change of the watched variable...
And that's it for the mighty watchers... why???

After a reality check, I realized that I needed some kind of horrible loop to check this collection, or else I had to implement some sort of callback to do this, whenever the var gets modified.

Anybody knows how this can be done in the cleanest way possible?


Important note:
I don't why, but it seems that some horrific bug in my code was gnawing my ankles...

Now that I've fixed it, both $watchCollection(expr, foo) and $watch(expr, foo, true) works as expected...

I was mislead by this SO post , in which an user comments:

[...] I don't see anything in your code that makes the subsequent requests (to check for new messages). Where does that happen?

I took his comments as proof of my hypothesis... my bad!

I'm leaving this question as a memento

Was it helpful?

Solution

I'm pretty sure a regular $watch will do this if you utilize the 3rd parameter (objectEquality). This will check if the objects are equal and not just references.

So, you can use something like this:

$scope.$watch('prop', function(value) {
   // do something
   }, true);  

The true value tells Angular to compare objects instead of references.

The documentation for this feature is with scope.

OTHER TIPS

below solution is bit of an hacking solution and should only be used if $watchCollection does not work. rather than watching on the array, watch on json

$scope.$watch(function() { 
  return angular.toJson($scope.array); 
},
function() {
  // watch logic
}

I am using above solution to watch on multiple arrays like below:

$scope.$watch(function() { 
  return JSON.stringify([$scope.array1, $scope.array2]); 
},
function() {
  // watch logic
}

you can user either of JSON.stringify or angular.toJson.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top