Home » Angularjs » How to stop $observe in AngularJS

How to stop $observe in AngularJS

Posted by: admin November 29, 2017 Leave a comment


I had recently some issues with jQuery plugins in directives in Angular not being properly cleaned and hence, creating Memory Leaks.

So, today, while I was working on tests to ensure that won’t happen, I realised that there is no way to stop observing.

var stopObserving = attrs.$observe('myProperty', function(newValue) {          

Since I thought it worked the same way it does on $watch but clearly it doesn’t. According to the docs, $observe will return the callback function, that’s it, the second argument.

I have this test:


    it('should have emptied the DOM node', function(){
    it('shouldn\'t have any more watchers', function(){

And it fails, cause there is one watcher. I’ve checked and the $destroy is being called and hence, the cleaning is done. However, how can I get rid of that watcher?

The code, in case you’re curious is here:



AngularJS 1.3 and above

In Angular 1.3 and above, $observe returns the deregister function, so deregistering $observe works exactly as for $watch:

var stopObserving = attrs.$observe(...);

AngularJS 1.2 and below

In AngularJs 1.2 there is no way to deregister an observer, and, as you rightly noted, $observe returns the callback function.

There is however currently a PR open to change $observe to also return a deregistration function similar to $watch and $on, unfortunately this is only triaged for the 1.3 release because of the breaking change. The PR is over here: https://github.com/angular/angular.js/pull/5609

Good news is it takes a full 3 new lines of code to implement the change, as per the PR, so if you can’t wait until the 1.3 release you can easily implement this yourself.


When you invoke the $watch() method, to create a binding, AngularJS returns a “deregistration” function. This function can then be used to unbind your $watch() listener – all you have to do is invoke this returned function and your $watch() listener will be removed.
To see this in action, take a look at the following code. In this demo, we’re watching the number of clicks that a link receives. And, if that number gets above 5, we’re going to show a message; however, once the message is shown, we remove the listener as it will no longer have any value.

visit: http://plnkr.co/edit/nciFRm9HTL3i8xYSUQJa?p=preview

As you can see, we’re storing the function reference returned by the $watch() statement; then, once the $watch() fires a few times, we invoke that stored method, unbinding the $watch() listener. If you watch the console log, you can see that the console.log() statements stop as soon as the “deregistration” function is called.


as a temporary solution you can do:

var key = 'myAttr';
    attrs.$observe(key, function(newValue) {
    delete attrs.$$observers[key];

or if your want to be really nifty:

attrs.$observe = function(key, fn) {
    attrs.$observe(key, fn);

    return function() {
       delete attrs.$$observers[key];   

var unobserve = attrs.$observe('myAttr', function(newValue){