31

Why does $watch trigger directly after page load and how can I prevent this?

http://jsfiddle.net/dcSRu/2/

function MyCtrl($scope) {
    // Init scope vars
    $scope.data_copy = {};

    // If data_copy changes...
    $scope.$watch("data_copy", function(newValue, oldValue) {

        alert("$watch triggered!");

    }, true);
}
Uli Köhler
  • 13,012
  • 16
  • 70
  • 120
tidelipop
  • 717
  • 2
  • 7
  • 10
  • This is also the case if you had a controller or directive which was initiated some time after page load. – Andrew Aug 27 '14 at 06:48

3 Answers3

49

On first run both values (newValue and oldValue) are equal, so you may easily escape it by checking for equality:

$scope.$watch("data_copy", function(newValue, oldValue) {
  if(newValue === oldValue){
    return;
  }
  alert("$watch triggered!");
});

PLUNKER

Stewie
  • 60,366
  • 20
  • 146
  • 113
  • 1
    Ahh, thanks! But can I really compare the two objects with ===, shouldn't I use something like underscore's _.isEqual(newValue, oldValue) ? – tidelipop Apr 08 '13 at 11:30
  • Probably, but I do already use underscore so I used that instead and it worked great. – tidelipop Apr 10 '13 at 21:59
  • @tidelipop Why you need _.isEqual, for $watch init, newValue oldValue will be the same. What's the initial value in your case ? – Huei Tan Apr 14 '14 at 09:52
  • 9
    Why does `$watch` even fire if `newValue === oldValue`? `$watch` is specifically designed to fire when those are NOT equal. – poshest May 23 '15 at 21:24
  • @poshest +1 - yes why is any of this necessary? – ajbraus Jul 25 '15 at 18:43
  • @poshest, on first change `oldValue==undefined` –  Oct 02 '15 at 10:42
2

Wrap $watch function into angular ready function.

angular.element(document).ready(function() 
{ 
  $scope.$watch("data_copy", function(newValue, oldValue) {
    alert("$watch triggered!");
  }, true);
})

When angular loads page. It changes values and $watch is triggered.

David Vareka
  • 252
  • 2
  • 6
0

There already have a very nice discussion in here:

How do I ignore the initial load when watching model changes in AngularJS?

$scope.$watch('fieldcontainer', function (new_fieldcontainer, old_fieldcontainer) {

if (typeof old_fieldcontainer === 'undefined') return;

// Other code for handling changed object here.

});

Community
  • 1
  • 1
SimonShyu
  • 95
  • 8