1

I have the following angularjs service

var assetLookUpTransformService = function($http, $q) {
this.data = null;
var self = this;

this.doStuff = function() {

    var defer = $q.defer();

    if (self.data) {
        defer.resolve(self.data[0].DisplayName);
    } else {
        $http({
            url: '../AssetLookup/GetAssetLookUp',
            method: "GET"
        }).success(function(response) {
            self.data = response;
            defer.resolve(self.data[0].DisplayName);
        });
    }
        return defer.promise;
    }
}

It works ok, in that once the $http request has returned all subsequent calls to "doStuff" return data from data rather than make a new request.

Then problem I have is that I am making a bunch of calls right after each other on page load. And what is happening is that the first call to doStuff will make an $http request, but also any calls to dostuff that happen before the first http request returns will also make a $http request.

Is there a way to make the calls to doStuff "wait" for the outstanding $http request to return before making there own.

Or is there a way to ensure the $http request only ever happens once?

2 Answers 2

3

Cache the promise, not the data. The data is encapsulated in the promise and will always be returned to whatever requests it.

var assetLookUpTransformService = function($http, $q) {
var self = this;

    this.doStuff = function() {
        if (!self.deferred) {
            self.deferred = $q.defer();

            $http({
                url: '../AssetLookup/GetAssetLookUp',
                method: "GET"
            }).success(function(response) {
                self.deferred.resolve(response[0].DisplayName);
            });
        }
        return self.deferred.promise;
    }
}
Sign up to request clarification or add additional context in comments.

Comments

0

Why don't you just make each of those calls after the first call to doStuff?

Example:

this.doStuff = function(afterRequests) {
   var defer = $q.defer();

if (self.data) {
    defer.resolve(self.data[0].DisplayName);
} else {
    $http({
        url: '../AssetLookup/GetAssetLookUp',
        method: "GET"
    }).success(function(response) {
        self.data = response;
        defer.resolve(self.data[0].DisplayName);
        //make each request in here.
        afterRequests.forEach(function(request) {
           $http(request).success(function(response) { 
           //use self.data here
           });
        });
    });
}
    return defer.promise;
}

If for some reason you have to make doStuff at the same time (e.g. it's very long running), then you could use $rootScope.$broadcast to target your controllers which may need to render the data.

Comments

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.