-1

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

sandeep
  • 175
  • 4
  • 14
  • 1
    Possible duplicate of [How do I return the response from an asynchronous call?](http://stackoverflow.com/questions/14220321/how-do-i-return-the-response-from-an-asynchronous-call) –  Jul 18 '16 at 17:24
  • 1
    @JarrodRoberson: The above isn't asynchronous. Sadly. – T.J. Crowder Jul 18 '16 at 17:29
  • @JarrodRoberson: The issue was that I was not able to return value for the onbeforeunload event as T.J. Crowder pointed out below. – sandeep Jul 18 '16 at 17:58

1 Answers1

0

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.

T.J. Crowder
  • 879,024
  • 165
  • 1,615
  • 1,639
  • Thank you for your feedback. It works. But it only works in IE. In chrome it works if I have the debugger(developer tools) turned on. Can you suggest anything regarding this? -- @T.J. Crowder – sandeep Jul 18 '16 at 17:56
  • @sandeep: Yes: My suggestion is don't try to do synchronous ajax from `onbeforeunload`. It doesn't work reliably cross-browser, and it's wrong to lock up the UI of the browser when the user is trying to leave while the ajax call is pending. As I said above, if you have an in-progress operation, you can flag that up without doing a synchronous ajax call when the user tries to leave. – T.J. Crowder Jul 18 '16 at 17:59
  • Well, actually the appointment creation happens in another system and there is no other way to determine it other than making a web service call. Are there any plugins which are better equipped to do operations such as above. Thank you @T.J. Crowder – sandeep Jul 18 '16 at 18:05
  • @sandeep: In that case, I'd probably schedule a periodic async check for whether the appointment has been created and keep the latest result of that check in a variable that you use in `onbeforeunload`. – T.J. Crowder Jul 18 '16 at 18:27
  • It worked if I used `window.addEventListener` and `beforeunload` event. It worked in all three browsers. Thanks again for your help!! – sandeep Jul 18 '16 at 21:37