7

I have clients that issue AJAX calls. These calls reference URLs that are protected by Spring Security on the sever side. If the user's session has timed out, I have a login form popup in a lightbox. After the user has successfully logged in, I would like the client to re-execute AJAX call.

Here's an example of the client side code that makes an AJAX call:

function handleSearchClick(evt) {
    var setupOptions = { 
        success: loadSearch,
        type: "POST",
        dataType: "json",            
        url:   "../search.ajax",
        error: handleError, // how can I pass callback info i.e. I want to be able to execute $("#searchForm").ajaxSubmit(setupOptions); from handleError? 
        timeout: 50000
    };                
    $("#searchForm").ajaxSubmit(setupOptions);
}

When the authentication fails, the server returns a 401 which results in the client calling handleError. Is it possible to pass a callback function to handleError? I would want the callback to re-execute

$("#searchForm").ajaxSubmit(setupOptions);

I have seen solutions to this problem where the server returns a success response on AJAX calls that have a session timed out. Then, the success function looks for something in the response to know the session timeout. The client then stores a callback function there. I prefer though to handle this in the error function.

James
  • 3,484
  • 17
  • 65
  • 104
  • did my answer worked for you? – Alex Jan 08 '13 at 21:41
  • Thanks for the answer. However, in the code below "But you could do the following", I'm not sure how handleError will be able to call $("#searchForm").ajaxSubmit(setupOptions). Could you please edit to provide more details on how this would be done? – James Jan 15 '13 at 23:54

3 Answers3

3

The request executed by

$("#searchForm").ajaxSubmit(setupOptions);

can be re-executed in the handleError function by calling

$.ajax(this);

There is no need to pass in a callback function to re-execute:

$("#searchForm").ajaxSubmit(setupOptions);
James
  • 3,484
  • 17
  • 65
  • 104
2

I've mentioned it here: How to send a form without refreshing the page?

It's the way of having a callback for the error handler.

$.ajax({
    url: siteUrl + 'fetch/search',
    type: "POST",
    data: formData,
    success: function(data) {
      .....
    },
    error:function(x,e){
        if(x.status==0){
            alert('You are offline!!\n Please Check Your Network.');
        }else if(x.status==404){
            alert('Requested URL not found.');
        }else if(x.status==500){
            alert('Internel Server Error.');
        }else if(e=='parsererror'){
            alert('Error.\nParsing JSON Request failed.');
        }else if(e=='timeout'){
            alert('Request Time out.');
        }else {
            alert('Unknow Error.\n'+x.responseText);
        }
    }
});

But you could do the following

function handleSearchClick(evt) {
    var setupOptions = { 
        success: loadSearch,
        type: "POST",
        dataType: "json",            
        url:   "../search.ajax",
        error: handleError(x,e), // this should do it
        timeout: 50000
    };                
    $("#searchForm").ajaxSubmit(setupOptions);
}
Community
  • 1
  • 1
Alex
  • 7,330
  • 20
  • 78
  • 147
  • 2
    error needs to be a reference to a function. However, in last code snippet you have an invocation of a function. – James Jan 15 '13 at 23:59
2

Closures to the rescue:

function handleSearchClick(evt) {
    var setupOptions = {
        success: loadSearch,
        type: "POST",
        dataType: "json",
        url: "../search.ajax",
        timeout: 50000
    };
    setupOptions.error = handleError(setupOptions);
    $("#searchForm").ajaxSubmit(setupOptions);
}

function handleError(setupOptions) {
    return function () {
        // handle error

        // then re-submit
        $("#searchForm").ajaxSubmit(setupOptions);
    };
}

Note that this creates a reference loop (setupOptions has a reference to the error function returned by handleError, the error function has a reference to setupOptions), but this should be easily garbage-collected by any decent browser.

Jeffery To
  • 11,698
  • 1
  • 26
  • 42
  • Thanks! This is a correct solution to the question. I think the built in jquery call $.ajax(this) will be better for handling errors from multiple types of request in a generic way. I did not realize that functionality existed until after posting my question. I gave +1 to your answer as it would great way to do this and would be my choice if the jquery call did not exist. – James Jan 18 '13 at 23:09