Search code examples
javascriptarraysangularjsangularjs-scopeangularjs-watch

angular $scope.$watch on array calling update function


In my plunk I have an array of integers, that I have attached $scope.$watch to. When I update the array, my $scope.$watch isnt firing a console.log. Why is my console.log not being called?

<!DOCTYPE html>
<html>

  <head>
    <script data-require="[email protected]" data-semver="1.5.0" src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.2/angular.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>

  <body ng-app="test" ng-controller="testArray">

    <div ng-repeat="item in MyArray track by $index"> {{item}}</div>
    <button ng-click="add()">testing Add</button>
  </body>

</html>
<script type="text/javascript">
    'use strict';
    var app = angular.module('test', []);

    app.controller('testArray',['$scope',function($scope){

      $scope.MyArray = [1,2,3,4]

      $scope.add = function(){
        $scope.MyArray.push($scope.MyArray.length+1);
      }
    $scope.$watch('MyArray' , function(){
      console.log($scope.MyArray);
    })
    }]);

</script>

Solution

  • You could use $watchCollection, It would be less expensive than the deep watcher by just providing true option in $watch function.

    $scope.$watchCollection('MyArray' , function(){
        console.log($scope.MyArray);
    })
    

    The $watchCollection() goes one-level deep and performs an additional, shallow reference check of the top level items in the collection.

    If you have really big array on which you wanted to keep watch then don't go for $watch with true(deep watcher). For 1000/2000 records, you will feel lag in angular bindings. So preferred approach would be avoid watcher as much as you can OR just go for $watchCollection