AngularJS - how to properly use $watch() and $watchCollection

AngularJS – how to properly use $watch() and $watchCollection

Many AngularJS developers don’t know how to properly use $watch() and $watchCollection(), and they write their own functions to track changes objects. Below is a piece of simple code to demonstrate differences between this two functions and situations when to use them.

$watch() is used to watch changes, for example in some input fields. This function always returns old value and new value.

$watchCollection() is used when trying to push something to a collection, or when removing some elements from it. This function returns previous collection and new collection.

And the third option. If you would like to detect changes inside your collections (deep watch), for example when you have collections and you want to modify some elements in ng-repeat you should again use $watch() function, but as a third parameter put boolean TRUE.

DEMO

script.js


(function() {
  'use strict';
  angular
    .module('app', [])
    .controller('WatchCtrl', WatchCtrl);
  WatchCtrl.$inject = ['$scope'];
  function WatchCtrl($scope) {
    var vm = this;
    vm.name = 'test';
    vm.collection = [{
      id: 0,
      value: 'test'
    }];
    vm.watchCollection = [];
    vm.deepWatchCollection = [];
    vm.watchCollectionCollection = [];
    vm.add = add;
    vm.remove = remove;
    vm.clear = clear;
    vm.refresh = refresh;
    function add(name) {
      vm.collection.unshift({
        id: 1,
        value: name
      });
    }
    function remove() {
      vm.collection.splice(1, 1);
    }
    function clear() {
      vm.collection = [];
      vm.name = '';
    }
    function refresh() {
      vm.collection = [];
      vm.watchCollection = [];
      vm.deepWatchCollection = [];
      vm.watchCollectionCollection = [];
      vm.name = '';
    }
    $scope.$watch('ctrl.name', function(newVal, oldVal) {
      vm.watchCollection.unshift({
        new: newVal,
        old: oldVal
      });
    });
    $scope.$watch('ctrl.collection', function(newVal, oldVal) {
      vm.deepWatchCollection.unshift({
        new: newVal,
        old: oldVal
      });
    }, true);
    $scope.$watchCollection('ctrl.collection', function(newVal, oldVal) {
      vm.watchCollectionCollection.unshift({
        name: newVal
      });
      vm.newValLength = newVal.length;
    });
  }
})();

This is the first part of series of articles on building real-time, highly scalable applications using AngularJS and Node.js frameworks.

author:Sebastian Superczyński