$watch vs $watchCollection

Exploring the differences between Angular $watch and $watchCollection

by th3uiguy

HTML

<div ng-controller="Controller">
  <textarea name="log" id="log" cols="40" rows="55"></textarea>  
</div>

JavaScript

function Controller ($scope, $element, $timeout){
  log('--Init:-------------');
  $scope.myArray = [
  	{one: '1'},
    {two: '2'},
    {three: '3'}
  ];
  $scope.myObj = {
  	one: '1',
    two: '2',
    three: '3'
  };
  $scope.str = 'string';
  
  $scope.$watch('str', watch);
  $scope.$watch('myArray', watch);
  $scope.$watch('myObj', watch);
  $scope.$watchCollection('myArray', watchCollection);
  $scope.$watchCollection('myObj', watchCollection);
  $scope.$watch('myArray', deepWatch, true);
  $scope.$watch('myObj', deepWatch, true);
 
  
  // Make changes to myArray
  $timeout(() => {
  	log('\n\n--myArray---------\nAdd element:');
  	$scope.myArray.push({four: 4});
  }, 10);
  $timeout(() => {
  	log('\nEdit an element:');
  	$scope.myArray[2].a = 'a';
  }, 30);
  $timeout(() => {
  	log('\nRemove an element:');
  	$scope.myArray.splice(2, 1);
  }, 50);
  $timeout(() => {
  	log('\nMove an element:');
  	var removed = myArray.splice(2, 1);
    $scope.myArray.splice(0, 0, removed);
  }, 70);
  $timeout(() => {
  	log('\nReplace the array:');
  	$scope.myArray = [1,2,3];
  }, 100);
  
  
  // Make changes to myObj
  $timeout(() => {
    log('\n\n--myObj----------\nAdd a property:');
    $scope.myObj.a = 'a';
  }, 120);
  
  $timeout(() => {
    log('\nEdit a property:');
    $scope.myObj.a = 'b';
  }, 140);
  
  $timeout(() => {
    log('\Delete a property:');
    delete myObj.a;
  }, 160);
  
  $timeout(() => {
    log('\nNull a property:');
    myObj.one = null;
  }, 180);
  
  $timeout(() => {
    log('\nReplace the object:');
    $scope.myObj = {test: 'test'};
  }, 200);
  
  
  // Make changes to str
  $timeout(() => {
  	log('\n\n--str---------\nReplace the string:');
  	$scope.str = 'string2';
  }, 210);
  
  
  function watch(){ log('watch'); }
  function watchCollection(){ log('watchCollection'); }
  function deepWatch(){ log('deepWatch'); }

  function log(msg){
  	var el = $element.find('textarea');
    el.val(el.val() + msg +...