AngularJS: $watch

by ozzymcduff

HTML

<button ng-click="setFoo('Something')">Set foo = 'Something'</button>

<button ng-click="foo = foo+1">Set $scope.foo += 1</button>

JavaScript

external = {
  foo: 'a'
};

function Watcher(reader) {
  var watches = {};

  this.watch = function(callback) {
    var id = Math.random().toString();
    watches[id] = callback;

    // Return a function that removes the listener
    return function() {
      watches[id] = null;
      delete watches[id];
    }
  };
  this.trigger = function() {
    var val = reader();
    for (var k in watches) {
      watches[k](val);
    }
  };
}

var externalFooObservable = new Watcher(() => external.foo);


angular.module('TestApp', [])
  .controller('MainCtrl', function($scope) {
    var unbind = externalFooObservable.watch(function(newVal) {
      console.log("external foo", newVal);
    });

    // Unbind the listener when the scope is destroyed
    $scope.$on('$destroy', unbind);
    // Variable
    var foo = 'Hello World';
    console.log('foo', foo);

    // Object
    var bar = {
      foo: 'Hi',
      bar: 'Hello'
    };
    console.log('foo', foo);

    $scope.foo = 'Helo';
    console.log('$scope.foo', $scope.foo);

    $scope.setFoo = function(value) {
      foo = value;
    };

    $scope.$watch(function() {
      return foo;
    }, function(newValue, oldValue) {
      console.log('foo', newValue);
    });


    $scope.$watch('foo', function(newValue, oldValue) {
      console.log('$scope.foo', newValue);
    });

    $scope.$watch(function() {
      return external.foo;
    }, function(newValue, oldValue) {

      console.log("external.foo", newValue);
    });
  });