Ensuring background AJAX requests have completed when leaving a page
To make things feel quicker on 88 Miles, I update the UI straight after an interaction (like punching in or out), even though in reality the AJAX request is still sitting there waiting for confirmation from the server. Generally, the AJAX request will complete correctly (and if it doesn’t a message gets popped up and the UI is restored to a pre-action state), however there is a chance that the user will close their browser or navigate away before everything completes, which may result in a project staying punched in which is less than ideal.
This little snippet of JS will allow you to check for pending AJAX requests, and throw up a warning dialog is a request is still pending.
jQuery example:
var ajaxInProgress = false;
function ajaxStart() {
ajaxInProgress = true;
}
function ajaxStop() {
ajaxInProgress = false;
}
$(window).bind('beforeunload', function(e) {
if(ajaxInProgress) {
return "There is a background process that hasn't completed yet. Reloading might result in data loss.";
}
});
Pure XHR example:
var requests = [];
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
if(this.readyState == 1) {
requests.push(this);
}
if(this.readyState == 4) {
var index = requests.indexOf(this);
// Remove the completed request from the request list - handles out of order responses
if(index != -1) {
requests.splice(index, 1);
}
}
}
window.onbeforeunload = function() {
if(requests.length != 0) {
return "There is a background process that hasn't completed yet. Reloading might result in data loss.";
}
}
Caveats
Tested on latest Chrome, Firefox, Safari and IE 9+.
It doesn’t work on the iPhone. Which is shit, because phones are the ones that need this the most. It works fine on Android and Windows Phone though.