Search code examples
javascriptangularjsangularjs-directiveangularjs-serviceangular-http

How to Handle multiple Ajax call calling same function?


Hi have 4 directives on the page, all directive require list of user. User List is stored in database which require hhtp request. As 4 directive are on the page at same time so 4 different ajax call has been sent to server for similar response.

And then the response is getting cached.

What can be done that all 4 directive recieves its user list and only one ajax is sended to server.

Code Inside Directive(self is this) (ajaxCallService is service)

ajaxCallService.getUser(function(response) {
                self.users = response;
                //Next operations
});

ajaxCallService Service

Variable
var userList = []

Method
if (!userList.length) {
          $http.post({
                url: #,
                data:#
            })
            .then(
                function(response) {
                        userList = response.allMembers;
                        callback && callback(userList);
                }
            );
        }else{
            callback && callback(userList);
        }

How can i prevent 4 ajax calls and only make 1 call and let other 3 wait for the response and pass response back?


Solution

  • You can use promises for this, to see if it is already running. Because services are singletons in angular, you know it is always a shared instance:

    var userList = [];
    var promise;
    
    function getUser() {
        // inject the $q service
        var deferred = $q.defer();
    
        if (userList.length) {
            // already got data, immediately resolve that one
            deferred.resolve(userList);
        }
    
        if (promise) {
            // a promise is already working on it, return this one
            return promise;
        } else {
            $http.post(...).success(function(response) {
                userList = response;
                deferred.resolve(response);
            });
        }
    
        // if this point is reached, this is the first call
        // assign the promise so other calls can know this one is working on it
        promise = deferred.promise;
        return promise;
    }