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

All we need is an easy explanation of the problem, so here it is.

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/

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

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.

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply