Asynchronous Ajax callback

I am making the following ajax call:

def myfunction(var1, var2){
b1. $.ajax({
        url: 'some_url2',
        type: "POST",
        data: {'mydata': var1, 'mydata2': var2},
        success: function (data) {
b2.        document.getElementById("successMessageAlert").style.display = "none";
        },
        error: function(xhr, errmsg, err) {
            alert('error1 occurred');
b3.  }
}

def function1() {
    $.ajax({
        url: 'some_url',
        type: "POST",
        data: formData,
        success: function (data) {
            var aData = JSON.parse(data);
b4.         myfunction(getCookie('selected_Id'), aData);
b5.         document.getElementById("successMessageAlert").style.display = "block";
b6.         document.getElementById("successMessageText").innerHTML = "<strong>Success!</strong> The encoding record was saved successfully.";
            }
        },
        error: function (xhr, errmsg, err) {
            alert('error occurred')
        }
    });
}

      

I am also using the following code snippet for csrf:

$.ajaxSetup({
    beforeSend: function (xhr, settings) {
        if (!csrfSafeMethod(settings.type) && sameOrigin(settings.url)) {
            xhr.setRequestHeader("X-CSRFToken", csrftoken);
        }
    }
});

      

The problem is that the instructions after myfunction

are executed before myfunction

. So, "successMessageAlert" appears briefly before hiding again.

I've used some breakpoints (b1-b6). Below is the order of their execution:

  • b4
  • b1
  • b3
  • b5
  • b6
  • b2
  • b3

Based on reading a few related SO posts, I know this problem must have something to do with the asynchronous nature of the ajax calls, function beforesend

and callbacks, but I can't seem to put 2 and 2 together. Please help.

PS: I need to change the title of the post. But I cannot describe this problem succinctly.

+3


source to share


3 answers


Actually, the flow of execution is absolutely correct. I don't consider it to be anything related. beforeSend

Now you need to understand the nature of JavaScript ajax call. Ajax Call asynchronous

in nature.

asynchronous

means that whenever an ajax call is made, JavaScript does not wait for the call to complete and move on to the next line of code.

For example, in your case

After the b1

code moved to -> b3

Since JavaScript did not wait for the call to complete

Now the question is when will be executed b2

.

It depends on the network traffic, once the ajax call is complete the code will execute b2

.

How to handle this case:

There are two ways:

a) I will not suggest this. Use async:false

as a parameter in ajax call. When this parameter is specified in the ajax call, it says JavaScript, expecting



b2

and don't go to b3

.

Why am I not suggesting this

The call is synchronous, if your request takes 3 seconds then your site doesn't respond for 3 seconds.

b) Callback using the second approach:

This is a bit tricky but the best approach.

First, you need to define the code that depends on the completion of the ajax call, you can put all this code inside the function and execute it after the ajax call completes

Below is an example:

    def myfunction(var1, var2 , callback){
     $.ajax({
            url: 'some_url2',
            type: "POST",
            data: {'mydata': var1, 'mydata2': var2},
            success: function (data) {
            document.getElementById("successMessageAlert").style.display = "none";
            callback(); //execute the passed function now
            },
            error: function(xhr, errmsg, err) {
                alert('error1 occurred');
      }
    }  





      def function1() {
        $.ajax({
            url: 'some_url',
            type: "POST",
            data: formData,
            success: function (data) {
                var aData = JSON.parse(data);
                     myfunction(getCookie('selected_Id'), aData ,function(){

                          //Code will get executed after ajax call completes

                         document.getElementById("successMessageAlert").style.display = "block";
                         document.getElementById("successMessageText").innerHTML = "<strong>Success!</strong> The encoding record was saved successfully.";          
                     });
                }
            },
            error: function (xhr, errmsg, err) {
                alert('error occurred')
            }
        });
    }

      

+1


source


try using ajax call like this async:false

in youmyfunction

$.ajax({
            url: 'some_url2',
            type: "POST",
            async:false,
            data: {'mydata': var1, 'mydata2': var2},
            success: function (data) {
           document.getElementById("successMessageAlert").style.display = "none";
            },
            error: function(xhr, errmsg, err) {
                alert('error1 occurred');
      }

      



Please check the answer if it helps

+1


source


In jQuery, ajax calls return a jqXHR object for asynchronous processing. Among other possibilities, it has a function .done

that binds a callback to get the ajax result after the request is done. It is very useful to return and use this object as it opens the door for various kinds of continuous processing.

As noted in other answers, it is not a great idea to make the ajax calls behave synchronously as this blocks all other processing and can lead to very bad UX.

You must use this in your code to manipulate only the UI:

function myfunction(var1, var2){
  // I guess the "successMessageAlert" should be here, no?
  document.getElementById("successMessageAlert").style.display = "none";
  return $.ajax({
        url: 'some_url2',
        type: "POST",
        data: {'mydata': var1, 'mydata2': var2},
/*       success: function (data) {
           document.getElementById("successMessageAlert").style.display = "none";
        },*/ // <- Bring this back if that really what you wanted...
        error: function(xhr, errmsg, err) {
            alert('error1 occurred');
  }
}

function function1() {
    $.ajax({
        url: 'some_url',
        type: "POST",
        data: formData,
        success: function (data) {
          var aData = JSON.parse(data);
          myfunction(getCookie('selected_Id'), aData).done(function () {
            document.getElementById("successMessageAlert").style.display = "block";
            document.getElementById("successMessageText").innerHTML = "<strong>Success!</strong> The encoding record was saved successfully.";
          });
        },
        error: function (xhr, errmsg, err) {
            alert('error occurred')
        }
    });
}

      

+1


source







All Articles