tags:

views:

677

answers:

5

I am using jQuery to make some ajax calls and wonder how people handle this situation.

  1. An ajax request is made to the server to retrieve some info.
  2. Before the request returns another request is made. The first request is now invalid and out of date.

How do I tell that the initial request is now invalid and can be ignored when it returns. I only want to display the results of the second request and ignore (or cancel) the first.

A: 

I've never been in this situation before, but you could send over a key that you increment when making the request and have the key sent back with the response. When the response arrives, you could then check the key to see if it is what you expected.

var incrementor = 1;
var lastSent = 0;

jQuery(document).ready(function() {

    jQuery('a.submitter').click(function(event) {
     event.preventDefault();
     lastSent = incrementor;
     incrementor++;
     jQuery.post(
      'some-url.php',
      {
       'request-id': lastSent,
       'other-data': 'some-data'
      },
      function( data, textStatus ) {
       if( data.requestId == lastSent ) {
        // Do stuff
       }
      },
      'json'
     );
    });

});
nickohrn
I like this approach, but what if you don't have control over the service definition?
bendewey
A: 

"How do I tell that the initial request is now invalid"

You DON'T...! You queue up Ajax Requests at the client layer and don't let them fire before the previous ones have returned and finished up their manipulation of the DOM...

You can get some details about how to do this at my blog about "how to create an Ajax library" at; http://ra-ajax.org/how-to-create-an-ajax-library-part-7-the-ra-ajax-class.blog

Thomas Hansen
This presents a bad user experience though.
Craig
-1 Cancelling a user request is a valid use case.
cletus
@Cletus - sure if your server is a "stupid databucket", but if you have business logic on your server (instead of in JS on client) then your Ajax request would probably actually *do* something which should affect client. Cancelling it then is obviously NOT a choice...
Thomas Hansen
+2  A: 

Keep a record of a variable (eg:"request_id") that identify the request. Add 1 to the variable at each new request. Only process the request if the request_id returned by the server is equal to the variable you have on the client.

My 2 cents.

Tiago
This is what I have considered.
Craig
@Craig: So it deserves a upvote, right? As you didn't have specified that on the original question.
Tiago
I certainly think it deserves an upvote +1
nickohrn
This is exactly what I do in these situations. It works wonderfully.
EndangeredMassa
+7  A: 

jQuery returns the XmlHttpRequest object from the call to ajax(), which I've used to achieve what you desire as follows:

var lastRequest;
function getSomeData() {
    if(lastRequest) {
        lastRequest.abort();
        lastRequest = null
    }
    lastRequest = $.ajax(...);
}

The net effect is that earlier requests' responses are ignored if a subsequent request is made.

Crescent Fresh
A: 

I prefer not to involve the service call, you may not always have control over the service definintion. I would like to see something like this

$(function() {
    $('.ajaxButton').click(function() {
        $.currentCallId = (new Date()).getTime();

        $.ajax({
            type: "get",
            url: 'http://www.google.com/',
            beforeSend: function(xhr) {
                this.callId = $.currentCallId;
            },
            success: function(data) {
                if (this.callId === $.currentCallId) {
                    // process it
                } else {
                    // throw it out
                }
            }
        });
    });
});
bendewey