Googman
Googman

Reputation: 141

How to watch a primitive service variable in controller with AngularJS?

I'm trying to use $watch for it. The $watch body firing at page initialization (with undefined in newValue) and not firing at "btnChangeIsLoggedIn" click.

<!DOCTYPE html>
<html data-ng-app="myApp">
<head><title>title</title></head>
<body>
    <script src="lib/angular/angular.js"></script>

    <div ng-controller="ctrl1">
        <input type="text" ng-model="isLoggedIn" />
        <input type="button" id="btnChangeIsLoggedIn" 
            value="change logged in" ng-click="change()" />
    </div>

    <script>
        var myApp = angular.module('myApp', []);

        myApp.service('authService', function () {
            this.isLoggedIn = false;
        });

        myApp.controller('ctrl1', function ($scope, authService) {
            $scope.isLoggedIn = authService.isLoggedIn;

            $scope.$watch("authService.isLoggedIn", function (newValue) {
                alert("isLoggedIn changed to " + newValue);
            }, true);

            $scope.change = function() {
                authService.isLoggedIn = true;
            };
        });
    </script>
</body>
</html>

What I'm doing wrong?

My code at JSFiddle: http://jsfiddle.net/googman/RA2j7/

Upvotes: 12

Views: 12809

Answers (1)

TheSharpieOne
TheSharpieOne

Reputation: 25726

You can pass a function that will return the value of the Service's method. Angular will then compare it to the previous value.

$scope.$watch(function(){
    return authService.isLoggedIn;
}, function (newValue) {
    alert("isLoggedIn changed to " + newValue);
});

Demo: http://jsfiddle.net/TheSharpieOne/RA2j7/2/

Note: the reason the text field value doesn't update is because the button only changes the service's value, not the $scope's You can also get rid of that initial alert (running of the change function) but comparing the newValue to the oldValue and only executing the statements if they are different.

Upvotes: 20

Related Questions