Monday, February 23, 2015

Function to wrap all your REST calls

I recently saw this code:

        private sendRequestToGetCustomerFeatures(): void {
            this.currentlyCallingApi = true;
            this.checkCustomerFeatures().then(() => {
                // success handler
                this.currentlyCallingApi = false;
            }, () => {
                // error handler
                this.currentlyCallingApi = false;
            });
        }

This is TypeScript and Angular so the "currentlyCallingApi" exists on an object that also has this function. Now, my first thought was, "use finally to have a condition that happens on success or failure". And then I think, return the promise! Always return the promise. My third thought was that this is a repeated pattern. Repeated patterns should be abstracted out into other objects. So here is some simple code:

    function callOnlyOnceBeforeCompletion(func) {
        var promise;
        return function() {
            if (!promise) {
                promise = func().finally(function(){
                    promise = null;
                })
                return promise;
            } else {
                return promise;
            }
        }
    }

Now this code takes in a function that takes a promise. When called you kick off the promise created by the function. Further calls do nothing until the promise finished. They will just return the already existing promise. Once it is finished the promise is destroyed and can be created and run again. Here is a jsfiddle link http://jsfiddle.net/willseitz/3rp3uezL/ to an example. This code is nice because it is isolated and easily testable. It is easy to use and you don't have to pollute your code with odd variables like "currentlyCallingApi". So the above call becomes something like:

sendRequestToGetCustomerFeatures = callOnlyOnceBeforeCompletion(checkCustomerFeatures);

No comments:

Post a Comment