Oam Psy
Oam Psy

Reputation: 8663

Angular scope not updating after service call

I have a controller and service.

The service performs a http.get and return true if successful and false if error.

However, in the controller, it receives true or false correctly, but the html of the binding always displays as true??

Controller:

app.controller('MyController', function($scope, MyService) {

    MyService.getData(function(isLoggedIn, userData) {

        var loggedIn = isLoggedIn;    
        $scope.isLoggedIn = loggedIn;
        $scope.myUser = userData;
        //$scope.$evalAsync();
        //$scope.$apply();            
    });    
});

app.factory('MyService', function($http, $q) {
    return {

        getData: function(isLoggedIn, userModel) {
            $http.get('../assets/data/data.json')
                .success(function(data) {
                    userModel(data);
                    isLoggedIn(true);
                })
                .error(function(data, status, headers, config) {
                    // If 400 or 404 are returned, the user is not signed in.
                    if (status == 400 || status == 401 || status == 404) {
                        isLoggedIn(false);
                    }                    
                });
        }
    }
});

HTML:

{{isLoggedIn}}

In the above, {{isLoggedIn}} is always true. Even when i modify the http call to:

$http.get('../blah/blah/blah.json')

In the effort to force a .error/fail.

I've tried $scope.$apply() and i keep getting the error of a digest cycle in process. help!!!

Upvotes: 0

Views: 496

Answers (1)

tymeJV
tymeJV

Reputation: 104775

I think you're a bit confused as to how the callbacks are working. Your isLoggedIn param in the service is the callback function that you're passing in. Your code corrected:

app.controller('MyController', function($scope, MyService) {

    /*
    The function(response) { is your callback function being passed to the service
    */
    MyService.getData(function(response) {
        var loggedIn = response.isLoggedIn;    
        $scope.isLoggedIn = loggedIn;
        $scope.myUser = response.userModel;           
    });    
});

app.factory('MyService', function($http, $q) {
    return {
        getData: function(callback) {
            $http.get('../assets/data/data.json')
                .success(function(data) {
                    //Execute your callback function and pass what data you need
                    callback({userModel: data, isLoggedIn: true});
                })
                .error(function(data, status, headers, config) {
                    // If 400 or 404 are returned, the user is not signed in.
                    if (status == 400 || status == 401 || status == 404) {
                        callback({isLoggedIn: false});
                    }                    
                });
        }
    }
});

You should be using promises... here's an even more refactored version:

app.controller('MyController', function($scope, MyService) {
    MyService.getData().then(function(response) {
        var loggedIn = response.isLoggedIn;    
        $scope.isLoggedIn = loggedIn;
        $scope.myUser = response.userModel;           
    });    
});

app.factory('MyService', function($http, $q) {
    return {
        getData: function() {
            return $http.get('../assets/data/data.json')
                .then(function(response) {
                    return {
                        userModel: response.data, 
                        isLoggedIn: true
                    };
                }, function(data, status, headers, config) {
                    // If 400 or 404 are returned, the user is not signed in.
                    if (status == 400 || status == 401 || status == 404) {
                        return {isLoggedIn: false};
                    }                    
                });
        }
    }
});

Upvotes: 1

Related Questions