3
\$\begingroup\$

I've wrote a pretty useful method to prevent multiple requests per single get url. There is a well known pattern - to store promise and return it for each next request. But there is too much copy/paste for my taste. So, please check my solution. Maybe you can give me advice to make it better or maybe point at any mistakes.

Here it is (working plunker):

promisedService.$inject = ['$q', '$http', '$httpParamSerializer'];
function promisedService($q, $http, $httpParamSerializer){
    
    var promisesInProgress = {};
    
    return {
        
        singleGet: singleGet
        
    }
   
    /** 
     * you can pass:
     * url
     * url and callback function
     * url, params and callback function
     */
    function singleGet(url){

        var params, preResolve;
        if(arguments.length == 3){
            preResolve = arguments[2];
            params = arguments[1];
        }
        else if(arguments.length == 2){
            if(typeof arguments[1] === 'function'){
                preResolve = arguments[1];
            }
            else {
                params = arguments[1]
            }
        }

        // creating unique key based on URL + params
        var requestUrl = _buildUrl(url, params);

        // checking for promise. If promise already exists - returning it
        if(promisesInProgress.hasOwnProperty(requestUrl)) {
            return promisesInProgress[requestUrl];
        }

        // else - saving new promise
        var deferred = $q.defer();
        promisesInProgress[requestUrl] = deferred.promise;
        
        // sending a request
        $http.get(url, params).then(function(response){
            console.log('server request');
            
            // if callback was passed, wrapping it in promise and returning
            // why do we need a callback. In case we need to cache data
            if(preResolve){
                $q.when(preResolve(response)).then(function(data){
                    deferred.resolve(data);
                });
            }
            else
            //else - returning data as is
                deferred.resolve(response);
            delete promisesInProgress[requestUrl];
        }, function(error){
            deferred.reject(error);
            delete promisesInProgress[requestUrl];
        });

        return deferred.promise;
    }

    /////////////////////////////// PRIVATE /////////////////////////////////

    function _buildUrl(url, params) {
        var serializedParams = $httpParamSerializer(params);

        if (serializedParams.length > 0) {
            url += ((url.indexOf('?') === -1) ? '?' : '&') + serializedParams;
        }

        return url;
    }
}

\$\endgroup\$

0

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.