6

Suppose I have a somewhat long-running jQuery Ajax call (say 5 seconds) as follows:

$.ajax({
    url: '/LongCall',
    type: 'POST',
    async: true,
    cache: false,
    datatype: 'json',
    success: function(data) {
      alert('Success!');
    },
    error(xhr, textStatus, errorThrown) {
      alert('Error!');
    }
});

Now suppose while waiting for my five second process to run the user grows impatient and decides to hit some sort of navigation on my page. What happens in the above call is the user gets the Error alert when he clicks a link.

I do want the error alert to display if there really is an error, but if all that happened is that the user decided to navigate away, I do not want the error alert to display. How can I do this?

In other words, is there some value I can check (xhr.status maybe?) that will tell me that the error that occurred is simply that the process was interrupted so I can know to ignore the error?

Thanks!

Robert MacGrogan
  • 357
  • 2
  • 12
  • 1
    Inspect the 2nd and 3rd arguments of the error callback. – Kevin B Mar 04 '13 at 23:00
  • Second argument is "error". Third argument is "". Neither is useful in this case from what I can tell. – Robert MacGrogan Mar 04 '13 at 23:59
  • In that case look through the properties of the first argument. – Kevin B Mar 05 '13 at 00:01
  • I've done this and can find nothing definitive. status = 0, and readyState = 0 as well, but I have no way of knowing if other conditions will cause this to happen. I'm looking for something reasonably definitive and I'm not sure I can find that this way. – Robert MacGrogan Mar 05 '13 at 00:20
  • Actually, I'm wondering if I can just check for readyState < 4, given this: http://stackoverflow.com/questions/632774/what-do-the-different-readystates-in-xmlhttprequest-mean-and-how-can-i-use-them – Robert MacGrogan Mar 05 '13 at 00:20
  • Wouldn't that be available on the first argument? – Kevin B Mar 05 '13 at 00:25
  • Found an on-point stackoverflow question finally: http://stackoverflow.com/questions/11341850/detect-ajax-request-interrupted-by-user-action – Robert MacGrogan Mar 05 '13 at 00:25
  • Yes, Kevin. xhr.readyState is what I'm talking about. I think that's what I'm looking for. Will update this as answered after I test it out a bit more. – Robert MacGrogan Mar 05 '13 at 00:26

2 Answers2

8

As near as I can tell, the best way to do this is to check xhr.readyState in your error handler. Any value less than 4 indicates that the process is still running so this means something is happening in the browser to interrupt it.

You also want to call xhr.abort() to attempt to stop the ajax process so the user doesn't have to wait for it to finish before the navigation actually happens, though for me the call to xhr.abort() does not actually speed things up.

$.ajax({
    url: '/LongCall',
    type: 'POST',
    async: true,
    cache: false,
    datatype: 'json',
    success: function(data) {
      alert('Success!');
    },
    error(xhr, textStatus, errorThrown) {
       if (xhr.readyState < 4) {
           xhr.abort();
       }
       else {
           alert('Error!');
       }
    }
});
Robert MacGrogan
  • 357
  • 2
  • 12
3

Reading the documentation, I would hazard a guess that your error handler should be like this:

error(xhr, textStatus, errorThrown) {
    if( textStatus != "abort") {
        alert("Error!");
    }
}
Niet the Dark Absol
  • 320,036
  • 81
  • 464
  • 592