1

I try to create a service for my user. I use a request http for get the current user. For avoid to call my server each time that I call the userService.getCurrentUser() I tried to send a variable if the request has already be send or call the server if it is the first time.

Here my service :

angular.module('UserService', []) 
.factory('UserService', function($q , $http, $rootScope,$timeout) {
    var currentUser = null;

    return {
        getCurrentUser: function() {
                if (currentUser == null){
                var config = {};

                config.cache = true;
                config.method = "GET"; 
                config.url = "users/get_current_user";
            return $http(config)
                .then(function(response) {
                    if (typeof response.data === 'object') {
                            currentUser = response.data.user;
                        return response.data.user;
                    } else {
                        // invalid response
                        return $q.reject(response.data);
                    }

                }, function(response) {
                    // something went wrong
                    return $q.reject(response.data);
                });
                }
                else{
                    return currentUser;
                }
        }
        };     
});

Unfortunately I call my request few time because the promise is not immediately resolved. How can I fix this to be sure to call my server once.

And how call this function from my controller because some time the return value is an promise so I use .then() and sometime it will be the value currentUser.

1 Answer 1

2

What you would need to save (and return in future invocations) is the promise itself. This way, it's guaranteed that:

  1. You will always get a promise object from your function (consistent behavior)
  2. You will never fire more than one request.

You can achieve this by changing your code as following:

angular.module('UserService', []) 
.factory('UserService', function($q , $http, $rootScope,$timeout) {
    var currentUserPromise = null;

    return {
        getCurrentUser: function() {
            if (currentUserPromise === null) {
                var config = {};

                config.cache = true;
                config.method = "GET"; 
                config.url = "users/get_current_user";
                currentUserPromise = $http(config)
                    .then(function(response) {
                        if (typeof response.data === 'object') {
                            return response.data.user;
                        } else {
                            // invalid response
                            return $q.reject(response.data);
                        }  
                    }, function(response) {
                        // something went wrong
                        return $q.reject(response.data);
                    });
            }
            return currentUserPromise;
        }
    }
};
Sign up to request clarification or add additional context in comments.

2 Comments

Hello urish, first thx for your answer. Great it works verry well so like it's a promise for get the data in my controller I need to do this : UserService.getCurrentUser().then(function(user){$scope.currentUser = user;}), instead of that $scope.currentUser = UserService.getCurrentUser() ?? it's little be constraining.
You welcome Flavien! Well, before AngularJS 1.2.0 you could get away with assigning the returned promise directly to the scope and this would work as expected, but since angular 1.2.0-rc3 this is deprecated (see github.com/angular/angular.js/issues/4158) and you should explicitly call .then() in your controller as you mentioned.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.