Jquery Ajax beforeSend and success,error & complete

347,364

Solution 1

Maybe you can try the following :

var i = 0;
function AjaxSendForm(url, placeholder, form, append) {
var data = $(form).serialize();
append = (append === undefined ? false : true); // whatever, it will evaluate to true or false only
$.ajax({
    type: 'POST',
    url: url,
    data: data,
    beforeSend: function() {
        // setting a timeout
        $(placeholder).addClass('loading');
        i++;
    },
    success: function(data) {
        if (append) {
            $(placeholder).append(data);
        } else {
            $(placeholder).html(data);
        }
    },
    error: function(xhr) { // if error occured
        alert("Error occured.please try again");
        $(placeholder).append(xhr.statusText + xhr.responseText);
        $(placeholder).removeClass('loading');
    },
    complete: function() {
        i--;
        if (i <= 0) {
            $(placeholder).removeClass('loading');
        }
    },
    dataType: 'html'
});
}

This way, if the beforeSend statement is called before the complete statement i will be greater than 0 so it will not remove the class. Then only the last call will be able to remove it.

I cannot test it, let me know if it works or not.

Solution 2

It's actually much easier with jQuery's promise API:

$.ajax(
            type: "GET",
            url: requestURL,
        ).then((success) =>
            console.dir(success)
        ).failure((failureResponse) =>
            console.dir(failureResponse)
        )

Alternatively, you can pass in of bind functions to each result callback; the order of parameters is: (success, failure). So long as you specify a function with at least 1 parameter, you get access to the response. So, for example, if you wanted to check the response text, you could simply do:

$.ajax(
            type: "GET",
            url: @get("url") + "logout",
            beforeSend: (xhr) -> xhr.setRequestHeader("token", currentToken)
        ).failure((response) -> console.log "Request was unauthorized" if response.status is 401
Share:
347,364
Rehan Anis
Author by

Rehan Anis

Homeopathic Consultant Cupping Therapist Clinical Psychologist Web Developer

Updated on July 09, 2022

Comments

  • Rehan Anis
    Rehan Anis almost 2 years

    I have a problem with multiple ajax functions where the beforeSend of the second ajax post is executed before the complete function of the first ajax.

    The loading class I am adding to the placeholder before sending is working for the first ajax call. However soon after the first ajax request completes the class is removed and never appends again on the second and further calls (remember recursive calls).

    While debugging it shows that the beforeSend function of the second ajax call is called first and the complete function of the first ajax call is called later. Which is obvious, because the return data inserted in the page from the first ajax call starts the second call.

    In short it's mixed up. Is there any way this can be sorted out?

    The function code is as follows

    function AjaxSendForm(url, placeholder, form, append) {
    var data = $(form).serialize();
    append = (append === undefined ? false : true); // whatever, it will evaluate to true or false only
    $.ajax({
        type: 'POST',
        url: url,
        data: data,
        beforeSend: function() {
            // setting a timeout
            $(placeholder).addClass('loading');
        },
        success: function(data) {
            if (append) {
                $(placeholder).append(data);
            } else {
                $(placeholder).html(data);
            }
        },
        error: function(xhr) { // if error occured
            alert("Error occured.please try again");
            $(placeholder).append(xhr.statusText + xhr.responseText);
            $(placeholder).removeClass('loading');
        },
        complete: function() {
            $(placeholder).removeClass('loading');
        },
        dataType: 'html'
    });
    }
    

    And the data contains the following snippet of javascript/jquery which checks and starts another ajax request.

    <script type="text/javascript">//<!--
     $(document).ready(function() {
        $('#restart').val(-1)
        $('#ajaxSubmit').click();
    });
    //--></script>
    
  • Rehan Anis
    Rehan Anis over 9 years
    Thanks for the update, I updated my code and replaced success, error and complete callback functions with the newly defined, promised functions fail, done and always. However they did not resolves the problem because the problem was something different as I applied the solution provided by @Nathan P
  • Rehan Anis
    Rehan Anis over 9 years
    I tried your solution and it gave me surprising results. First of all I used the var requestNumber = 0 and ++ it in beforeSend and checked it in complete/always. It shows the requestNumber == 2 and -- results in 1 which returns false in the check and loading class isn't removed. However it is never removed because I don't know why, it is generating one additional request for the whole sequence. Now the culprit is found, I think it's easy to resolve or post a bug request.
  • Robot Boy
    Robot Boy almost 9 years
    If the function fails, then it goes to error as well as complete. What if I only want it at complete, can I return 1 at the end of complete so it doesn't go to error?