sandeep sandeep - 4 months ago 31
Javascript Question

onbeforeunload doesn't take return string within a ajax call

I have to make an ajax call and decide based on the response whether to navigate away from a page or not. Here is what I've tried so far.

window.onbeforeunload = function(e) {
$.when($.ajax({
url: checkUrl,
async: false,
type: 'GET',
})).then(function(data, textStatus, jqXHR){
if(data===false)
return "Appointment not created yet. Do you wish to leave?";
else
return false;
});}


When I use the debugger to check the flow of control it seems to wait till the data is returned but it would not display the alert box.

I am not sure what I am doing wrong. I know there have been similar questions but could not find a solution. Help me find a way to make it work

Answer

You're not returning the string from your onbeforeunload function. You're returning it from the then callback.

You need to set a variable that you use to return from the main function instead:

window.onbeforeunload = function(e) {
    var result = undefined;
    $.when($.ajax({
        url: checkUrl,
        async: false,
        type: 'GET',
    })).then(function(data, textStatus, jqXHR){
        if(data===false) {
            result = "Appointment not created yet. Do you wish to leave?";
        }
    });
    return result;
};

Side note: There's no need for the $.when in that, you can use the "promise" returned by $.ajax directly:

window.onbeforeunload = function(e) {
    var result = undefined;
    $.ajax({
        url: checkUrl,
        async: false,
        type: 'GET',
    }).then(function(data, textStatus, jqXHR){
        if(data===false) {
            result = "Appointment not created yet. Do you wish to leave?";
        }
    });
    return result;
};

Side note 2: Insert usual note here about how synchronous ajax blocks the UI of the browser. If you're doing an appointment creation, surely you can set a client-side variable when you start creating it, then clear it when you're done, and use that to know whether to show a message?

Side note 3: Modern browsers ignore the message you return and just show something generic. I'm not saying you should change anything (because there are still some that show it, for now), just mentioning it so you don't go nuts trying to figure out why you're getting a message, but not your message.

Side note 4: Your then callback will only receive a single argument. The three arguments you've listed are the ones passed to the success callback, not the then callback.