3

I am trying to use $watch, however it's not firing when I expect it to.

Why is the below code not firing when $scope.string changes?

$scope.string = 'Hello.';
$scope.timesChanged = 0;

$scope.$watch('string', function (newValue) {
    $scope.timesChanged =+ 1;
});

$scope.string = 'How are you';
$scope.string = 'doing today?';

Here's a fiddle

Patrick Reck
  • 11,246
  • 11
  • 53
  • 86
  • Possible duplicate of [AngularJS : Basic $watch not working](https://stackoverflow.com/questions/15664933/angularjs-basic-watch-not-working) – AncientSwordRage Jun 02 '17 at 11:26

3 Answers3

3

It doesn't fire because there is no way Angular can know that you changed a string immediately after you had declared it. There is nothing that triggers new digest loop in this case, so $watch won't fire. Basically this is the same as if you were to write

$scope.string = 'Hello.';
$scope.string = 'How are you';
$scope.string = 'doing today?';

$scope.timesChanged = 0;

$scope.$watch('string', function (newValue) {
    $scope.timesChanged =+ 1; // you probably want += 1 here.
});

Watcher is registered in the same digest loop execution with string variable initialization.

dfsq
  • 191,768
  • 25
  • 236
  • 258
2

I think the problem is that your watch will not be triggered because the changes to scope happens in the same round of scope updating than the watch creation. You are initialising the controller so everything will be applied before angular can check anything. The watch is not active.

sam
  • 3,441
  • 2
  • 33
  • 42
2

Your $watch is fine, you just expect the wrong result.

The $watch function is set to watch only after the controller is first compiled, after that it works.

I updated your fiddle so you can see it in action:

http://jsfiddle.net/S9rV2/27/

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

function MyCtrl($scope) {

    $scope.string = 'Hello.';
    $scope.timesChanged = 0;

    $scope.$watch('string', function (newValue) {
        $scope.timesChanged++;
    });

    $scope.string = 'How are you';
    $scope.string = 'doing today?';

}
<div ng-controller="MyCtrl">{{ timesChanged }}
    <br/>
    <input type="text" ng-model="string"></input>
</div>
Ben Diamant
  • 6,186
  • 4
  • 35
  • 50