Sunday, August 17, 2014

How to cancel all the old XHR (http / ajax ) requests on state change (url change) - AngularJS Interceptor

11:31 PM Posted by jinto jose , , 2 comments
I am working on an AngularJS app which earlier was a jquery based web app. Still some global utilities are using jquery and we haven't yet converted that fully to AngularJS.

The whole app workflow is now handled with state changes using Angular UI Router. So, on state change, we will send the XHR requests for partial templates which will be filled on content area and also other functionalities required for the new state.

Now, we face an issue.  If we switch the navigation fast.. ie. if we change state fast, the html of the old state is first showing on the content area, even though it is not relevant any more.

So, I did some google search and found some useful posts.

Cancelling Ajax requests in AngularJS Applications

Interceptors in AngularJS and Useful Examples

Aborting An AJAX Request In AngularJS Using httpi

Here is the summary of what I got from these posts and others:

1. We can create a custom interceptor for AngularJS http requests. With this custom interceptor, we can add some custom functionalities for the following states:
a. request - On request success
b. requestError - On request failure
c. response - On response success
d. responseError - On response failture

2. Jquery Ajax has a ajaxSend function. In that we can get the xhr object.


So, lets do this step by step. I am not going to tell how to create the interceptor because which is clearly given in the above posts.

First we need to save all the requests so that we can cancel them later if needed.

So, first lets create an empty object.


In currentRequests, I have created two objects, http and ajax, for handling angular http requests, and jquery ajax requests respectively.

First, we will save the jquery ajax requests using the ajaxSend function.



Here we will get xhr as a parameter. So, we just need to save it. I am saving url also as the key, in case it is required at a later point.


Now, we have to save the Angular http requests.For the we have to check the request property of our  custom Interceptor. request function has a config parameter which contains all the info for the http request. In that, timeout property is the one we are interested in. If we check the angular code, we can see that, timeout is a promise which if resolved will do xhr abort. So, to use this, we we create a custom deferred object using $q and we will save the deferred object.





In this code, we are creating the deferred object, deferred. Promise object of the deferred is passed to config.timeout property. We will save our deferred object in currentRequests object.


Now that we have saved all the requests, we just need to loop through each xhr objects and just abort it.



I haven't finalized on it. Please add your suggestions/corrections in the comments.

You can see the gist here  - GlobalAjaxInterceptor

2 comments:

  1. From my point Angularjs Training In Hyderabad has only difference. It is learning at Hyderabad helped me in many ways and learning from the informative weblogs like this helped me to connect to more examples, realtime scenarios and case-studies. Thanks a lot.

    ReplyDelete
  2. Angularjs training is essential for developing any single page web application. You have to learn Angularjs indepth to creating enterpirse SPA application.

    Angularjs Training
    Angular.js Course
    Angularjs Online Training
    Angularjs Training in Chennai
    AngularJS Interview Questions

    ReplyDelete