1

I have the following action:

   $('.sub_outworker').live('click', function() {

                var input = $(this);
                var current_div = input.parents('div.report');
                var current_div_id = current_div.attr('id');
                var replace_div = current_div.children('div').first();
                var submission = submit_form(input, replace_div);
                var i = 0;
}

The submit_form() function looks like this:

function submit_form(input, replace_div) {
            var form = input.parents('form');

            loading_gif(replace_div);

             $.ajax({
                type: 'POST',
                url: form.attr('action'),
                data: 'ajax=true&' + form.serialize(),
                success: function(data) {
                    get_json();

                    if(data == 'success') {
                        return 'success';
                    }
                    else {
                        return 'failed';
                    }
                }
            });
        }

I want to check whether submission == failed and if it does run submit_form again (ie. give the function a second chance to work - mainly because it occasionally fails validation due to a mismatch in tokens). I'm not sure how to go about this though!

8
  • 2
    You cannot return any value from the success callback. Commented Jan 5, 2012 at 21:58
  • submit_form does not return anything. Commented Jan 5, 2012 at 21:59
  • That probably explains why I couldn't get my attempts to work earlier! Commented Jan 5, 2012 at 22:06
  • Once the success callback has completed is it possible to return something, or do any subsequent actions also need to be placed in the callback? Commented Jan 5, 2012 at 22:07
  • 1
    @MДΓΓ: Well, even deferred objects only accept callbacks. So you can say everything has to handled with callbacks if you deal with asynchronous code. Commented Jan 5, 2012 at 22:21

3 Answers 3

2

If you just want to run it one more time, the easiest (and IMO cleanest) way might be to use deferred objects [docs]:

function submit_form(input, replace_div) {
    var deferred = new $.Deferred();
    var form = input.parents('form');

    loading_gif(replace_div);

     $.ajax({
        type: 'POST',
        url: form.attr('action'),
        data: 'ajax=true&' + form.serialize(),
        success: function(data) {
            get_json();

            if(data == 'success') {
                deferred.resolve(data);
            }
            else {
                deferred.reject(data);
            }
        }
    });

    return deferred;
}

Then you can do:

var request = submit_form(input, replace_div);
request.fail(function() {
    submit_form(input, replace_div);
}).done(function() {
   // request was successful, do something
});

Deferred objects provide great flexibility with asynchronous calls and let you easily decouple code. Of course if you want to see the repeated attempt to make the Ajax call as a "feature" of the submit_form function or if you want to repeat it more than once, then @Matt's answer seems to be the better way.

Sign up to request clarification or add additional context in comments.

Comments

2

It has to be done in the $.ajax() callback.

$('.sub_outworker').live('click', function() {

    var input = $(this);
    var current_div = input.parents('div.report');
    var current_div_id = current_div.attr('id');
    var replace_div = current_div.children('div').first();
    submit_form(input, replace_div);
}

function submit_form(input, replace_div) {
    var form = input.parents('form');

    loading_gif(replace_div);

     $.ajax({
        type: 'POST',
        url: form.attr('action'),
        data: 'ajax=true&' + form.serialize(),
        success: function(data) {
            get_json();

            if(data == 'success') {
                submit_form.failCount = 0;
            }
            else if (!submit_form.failCount) {
                submit_form.failCount++;
                submit_form(input, replace_div);
            }
        }
    });
}

5 Comments

It could also be interesting to utilize deferred objects to be more flexible, but this is a simple solution which works. +1 :)
Looks like we posted similar answers. Only difference I can see is that I restructured slightly to avoid re-serialising the data on the form...
@bland: Ooook, with so much support ;) My original solution suggested to use the deferred object returned by $.ajax but that would only fail if the request itself fails, not when you just get a different value than success. You can still use your own deferred object though. See my updated answer.
@MДΓΓБДLL was a close run thing, have used Felix deferred object suggestion
@bland_dan no worries, I agree that his solution is cleaner for a one-off retry.
0

Could you do something like this? Note, I'm not 100% sure what you're expecting to get back from the server, or exactly how your page is structured.

function submit_form_ajax(serializedData, numAttempts) {

     numAttempts--;

     $.ajax({
        type: 'POST',
        url: form.attr('action'),
        data: 'ajax=true&' + serializedData,
        success: function(data) {
            get_json();

            if(data !== 'success') {
                if( numAttempts >= 1 ) {
                    submit_form_ajax(serializedData, numAttempts-1);
                }
            }
        }
    });

}

function submit_form(input, replace_div) {
    var form = input.parents('form');

    loading_gif(replace_div);

    submit_form_ajax(form.serialize(), 2);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.