Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS $watch strange behavior during controller initialization

I have a code snippet:

var app = angular.module('Demo', []);

app.controller('DemoCtrl', function ($scope) {
  function notify(newValue, oldValue) {
    console.log('%s => %s', oldValue, newValue);
  }

  $scope.$watch('collection.length', notify);
  $scope.$watch('my', notify);

  $scope.collection = [];  
  $scope.my = 'hello';
});

$watch fires initially. And this code snippet will output:

0 => 0
hello => hello 

Is it correct behavior? Of course I could check values for for equality, but what reasons for such as behaviour?

P.S. You could try this sample online: http://jsbin.com/otakaw/7/edit

like image 293
ValeriiVasin Avatar asked Jun 27 '13 08:06

ValeriiVasin


1 Answers

According to documentation:

The listener is called only when the value from the current watchExpression and the previous call to watchExpression are not equal (with the exception of the initial run, see below).

After a watcher is registered with the scope, the listener fn is called asynchronously (via $evalAsync) to initialize the watcher. In rare cases, this is undesirable because the listener is called when the result of watchExpression didn't change. To detect this scenario within the listener fn, you can compare the newVal and oldVal. If these two values are identical (===) then the listener was called due to initialization.

like image 156
ValeriiVasin Avatar answered Oct 12 '22 23:10

ValeriiVasin