Azima
Azima

Reputation: 4151

execution out of order inside ajax callback function javascript

I have a following ajax operation that is intended to (1) show spinner gif before sending ajax request, and after after the request is complete, (2) hide the gif and 3 display appropriate alert messages. Finally (4) reload the page.

Here's the code:

$.ajax({
   url: rUrl,
   data: {
      id: rID,
      requisitionStatus: rStatus,
      comment: rComment
   },
   type: "POST",
   cache: false,
   beforeSend: function() {
      $("#requisitionStatusDialog").dialog('close');
      $('#ajax_loader_my').show();
   },
   success: function(data, resp) {
      var json = data;
      var obj = JSON && JSON.parse(json) || $.parseJSON(json);
      if (obj.status == "success") {
         alert('Success! ' + obj.message);
         location.reload();
      } else if (obj.status == "error") {
         alert('Error!' + obj.message);
      }
   },
   error: function(data, resp) {
      $("#updateDialog").dialog('close');
      console.log(resp);
   },
   complete: function() {
      $('#ajax_loader_my').hide();
   }
});

But in this case, alert pops up first while the spinner gif still shows up, and reloads the page after clicking OK.

I even tried hiding the gif in success callback itself instead of using complete:

success: function(data, resp) {
  var json = data;
  var obj = JSON && JSON.parse(json) || $.parseJSON(json);
  if (obj.status == "success") {
     $('#ajax_loader_my').hide();
     alert('Success! ' + obj.message);
     location.reload();
  } else if (obj.status == "error") {
     alert('Error!' + obj.message);
  }

},

Both gives the same result.

Upvotes: 4

Views: 96

Answers (4)

stan chacon
stan chacon

Reputation: 768

Hi you should try to use promises here is the documentation Jquery promises, I made this on the fly it can have some errors but is just an example:

$( function() {
  function AjaxCall(rID,rStatus,rComment){
    return $.ajax({
      url: 'request.php',
      data: {
        id: rID,
        requisitionStatus: rStatus,
        comment: rComment    
      },
      type: "POST",
      cache: false,
      beforeSend: function() {
        $("#requisitionStatusDialog").dialog('close');
        $('#ajax_loader_my').show();
      }
    })
  }


  $( "#requisitionStatusDialog" ).dialog();

  $("#yourbuttonInputId").on('click',function(event) {
    AjaxCall().done(function(data,response){
      var obj = JSON.parse(data);
      if (obj.status == "success") {
        alert('whe are on done!');
      }
    }).fail(function(data,response){
      $("#updateDialog").dialog(' close');
    }).always(function(data){
      if(confirm('You have finished the request.  Click OK if you wish to continue ,click Cancel to reload the page.'))
      {
        $('#ajax_loader_my').hide();
        $("#requisitionStatusDialog").dialog('open');
      }else{
        location.reload();
      }

    });
  });
} );

EDIT: Check this jsfiddle it will guide you to elaborate your code

Hope it Helps

Upvotes: 1

Khurram Ishaque
Khurram Ishaque

Reputation: 798

I would rather suggest to use an empty div or span with an Id. Than display success in the html of that div. For Example:

$('#ajax_loader_my').hide();    
setTimeout(function () { 
    $('#successDiv').html('Success! ' + obj.message);
    location.reload();
}, 2000);

Upvotes: -1

RK_15
RK_15

Reputation: 939

Rewrite the code this way, this will put your alert and location related code in event queue which will run when it will be free.

if(obj.status=="success") { 
      $('#ajax_loader_my').hide(); 
      setTimeout(function(){
          alert('Success! '+obj.message);
          location.reload();
      },0);
}

Upvotes: 1

TrevTheDev
TrevTheDev

Reputation: 2737

The reason your alert pops up before the spinner is hidden is the success code runs before complete which hides the spinner. The reason it reloads is because after the alert you send location.reload();

Check that $('#ajax_loader_my').hide(); is actually hiding the spinner. The element that is or contains the spinner in your html must be have its id set to ajax_loader_my.

If you open Chrome or Firefox Dev tools you should be able to send $('#ajax_loader_my').hide() and see what happens.

Upvotes: 2

Related Questions