Ian Muir
Ian Muir

Reputation: 911

Changed value on AngularJS Service not triggering watch within directive

I'm having an issue getting a watch to work within a directive. I've put together a simple example here. http://plnkr.co/edit/A7zbrsh8gJhdpM30ZH2P

I have a service and two directives. One directive changes a property in the service, and another directive has a watch on that property. I expected the watch to fire when the property is changed but it doesn't.

I've seen a few other questions like this on the site, but the accepted solutions on them have not worked here. I've considered using $broadcast or trying to implement an observer, but it seems like this should work and I don't want to over complicate things if possible.

Upvotes: 9

Views: 6173

Answers (2)

tanguy_k
tanguy_k

Reputation: 12283

Mark Rajcok' answer is incomplete. Even with angular.copy(), $watch listener will be called once and never again.

You need to $watch a function:

$scope.$watch(

  // This is the important part
  function() {
    return demoService.currentObject;
  },

  function(newValue, oldValue) {
    console.log('demoService.currentObject has been changed');
    // Do whatever you want with demoService.currenctObject
  },
  true
);

Here the plunker that works: http://plnkr.co/edit/0mav32?p=preview

Open your browser console to see that both the directive and the demoService2 are notified about demoService.currentObject changes.

And btw angular.copy() is not even needed in this example.

Upvotes: 28

Mark Rajcok
Mark Rajcok

Reputation: 364677

Instead of

this.currentObject = newObject;

use

angular.copy(newObject, this.currentObject);

With the original code, the viewer directive is watching the original object, {}. When currentObject is set to newObject, the $watch is still looking for a change to the original object, not newObject.

angular.copy() modifies the original object, so the $watch sees that change.

Upvotes: 4

Related Questions