AngularJS : Watching ($watchCollection) scope variable collections

AngularJS : Watching ($watchCollection) scope variable collections

by Daan De Smedt

HTML

<b>WatchCollection</b>
<br/> Collection watches watch for changes in arrays, array-like objects, and objects. They are triggered by new, removed, replaced, and reordered items, keys, or values in those arrays and objects. They do not, however, watch the items, keys, or values themselves.

<br/>
<br/>

<div ng-app="app" ng-controller="BasicController as vm">
  <b>vm.myArr</b>
  <br/>
  <pre>{{vm.myArr | json}}</pre>
  <br/>
  <br/>
  <b>vm.myObj</b>
  <br/>
  <pre>{{vm.myObj | json}}</pre>
  <br/>
  <br/>
  <b>Re-init</b>
  <br/>
  <button ng-click="vm.reinit()">Re-init (watch triggered)</button>
  <br/>
  <br/>
  <b>Remove actions</b>
  <br/>
  <button ng-click="vm.myArr = []">Remove myArr (watch triggered)</button>
  <br/>
  <button ng-click="vm.myObj = []">Remove myObj (watch triggered)</button>
  <br/>
  <br/>
  <b>Edit content actions</b>
  <br/>
  <button ng-click="vm.myObj.title = 'Matrix movie updated'">Update content on myArr (1st level | watch is triggered)</button>
  <br/>
  <button ng-click="vm.myObj.content.cover = 'hard cover'">Update content on myArr (> 1st level | no watch is triggered)</button>
  <br/>
  <br/>
  <button ng-click="vm.myArr[0] = 99">Update content on myArr (watch triggered)</button>
  <br/>
  <button ng-click="vm.myArr.push(8)">Push element to myArr (watch triggered)</button>
  <br/>
  <button ng-click="vm.myArr.pop(vm.myArr.length-1)">Pop last element in myArr (watch triggered)</button>
  <br/>
  <button ng-click="vm.deleteMyObjContent()">Delete myObj content inner object (watch triggered)</button>
  <br/>
</div>

JavaScript

angular
  .module('app', [])
  .controller('BasicController', BasicController)

function BasicController($scope) {
  /* declare VM */
  var vm = this;
  vm.reinit = init;
  vm.deleteMyObjContent = deleteMyObjContent;

  /* functions */
  
  function deleteMyObjContent() {
    delete vm.myObj.content;
  };

  function init() {
    // set myObject as array
    vm.myObj = {
      title: 'Matrix movie',
      content: {
        amount: '4 disks',
        cover: 'soft cover'
      }
    };
    // set myArr as array
    vm.myArr = [3, 1, 4, 1, 5, 9];
  }
  // init
  init();

  // watchers
  $scope.$watchCollection('vm.myObj', function(newVal, oldVal) {
    console.log('myObj watch callback');
  }, true);

  $scope.$watchCollection('vm.myArr', function(newVal, oldVal) {
    console.log('myArr watch callback');
  }, true);

}