0

I got stuck finding the issue in my code below:

function fillStateList(cid) {
     $.ajax(
        {
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: someurl,
            data: "{'countyId': '" + cid + "'}",
            dataType: "json",
            success: function (data) {
                if (data.d.length > 0) {
                    //alert('r- ' + stateId); // <-- if uncomment this line, the code works fine !    
                    // code to bind select list
                                       }
                                     }
         });
}

I am calling fillStateList 4 times sequentially to bind 4 different select list but sometimes its working and sometimes not!

But if I uncomment alert('r- ' + stateId) to make sure the success events calling for each request, its working fine (i.e. all select lists successfully binding!)

Also tried: async: false

tutankhamun
  • 880
  • 2
  • 11
  • 21
Ashok Damani
  • 3,896
  • 4
  • 30
  • 48
  • Sounds like you have a race condition. Is the order in which the AJAX requests complete important? If so, you should chain them one after the other. – Rory McCrossan May 07 '14 at 08:55
  • If you change alert to console.log, does it still work and are there as many log entries as expected? – loafer May 07 '14 at 08:57
  • @Rory McCrossan : how to chain them ? – Ashok Damani May 07 '14 at 08:57
  • Make the first AJAX request, and fire the next one recursively in the callback. – Rory McCrossan May 07 '14 at 08:58
  • Make subsequent AJAX requests from the `success` handler. – setec May 07 '14 at 08:59
  • @RoryMcCrossan not really..you cant say that..AJAX never fails into race condition. Your client can request billion of AJAX request to a server. If your server is multithreaded to handle it then it will process them parallely o/w will do it sync but will never fail.Correct me if I am wrong..Comment will be appreciated . – Deepak Ingole May 07 '14 at 09:03
  • where is `// code to bind select list`. Quite unclear picture seems like you are victim of [How to return the response from an AJAX call?](http://stackoverflow.com/questions/14220321/how-to-return-the-response-from-an-ajax-call).. – Deepak Ingole May 07 '14 at 09:04
  • @Pilot yes, that's true. What I mean is that the code in his success handlers need to be performed in a set order .: race condition is breaking the logic. – Rory McCrossan May 07 '14 at 09:07
  • @RoryMcCrossan see my answer on how to chain them – Luke May 07 '14 at 09:07
  • @Rory McCrossan: no, its not like that. this is a custom function, which is calling from different js files simultaneously – Ashok Damani May 07 '14 at 09:09
  • @RoryMcCrossan : `async: false` not working ! – Ashok Damani May 07 '14 at 09:19

3 Answers3

0

It is possible that alert breaks something down, if it is called asynchronously from two different sources, e.g. the response from a server.

alerting is also not the best way to debug your data. use console.log instead, which is a much better way to debug your data. You can pass an object or an array and the developer console (e.g. in chrome or firefox´ firebug?) will diplay it nicely

to chain your ajax request, you might want to use Deferred.

$.when(fillStateList(12), fillStateList(13), fillStateList(14), fillStateList(15))
    .then(function() {
        alert("all done");
    });

here I´m using $.when (see Docs) to chain the deferreds.

You might also use the arguments in the done callback, where each argument is the deferred passed into when. See this example i copied from jquery directly

$.when( $.ajax( "/page1.php" ), $.ajax( "/page2.php" ) ).done(function( a1, a2 ) {
   var data = a1[ 0 ] + a2[ 0 ]; // a1[ 0 ] = "Whip", a2[ 0 ] = " It"
   if ( /Whip It/.test( data ) ) {
       alert( "We got what we came for!" );
   }
});

Here a1 is the reference to the first ajax request, and a2 the reference to the second. here you can also see if one did not work out...

Luke
  • 8,235
  • 3
  • 22
  • 36
0

You have a condition where your AJAX request have to be completed before next AJAX request is performed.

To make it work, do one of two options:

  1. Make subsequent ajax call from success function, to ensure that next call occurs when previous call is completed.

  2. Make AJAX calls synchronized:

$.ajax({
    async: false,
    ...
}
setec
  • 15,506
  • 3
  • 36
  • 51
0

Solved the problem !

// global variable to check whether the fillStateList already running (waiting for response) or not             
var IsBindingState = false;

// An extension method to fillStateList function to synchronize the requests (not to call fillStateList directly, use this method)
function fillStateListSync(cid) {
                    if (!IsBindingState) {
                        fillStateList(cid);
                    }
                    else {
                        var loop = setInterval(function () {
                            if (!IsBindingState) {
                                fillStateList(cid);
                                clearTimeout(loop);
                            }
                        }, 100);
                    }
                }

// function to bind state list
function fillStateList(cid) {
     IsBindingState = true;
     $.ajax(
        {
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: someurl,
            data: "{'countyId': '" + cid + "'}",
            dataType: "json",
            success: function (data) {
                if (data.d.length > 0) {
                    //alert('r- ' + stateId); // <-- if uncomment this line, the code works fine !    
                    // code to bind select list
                                }
                         IsBindingState = false;
                      },
            error: function (result) {
                         IsBindingState = false;
                        }
         });
}
Ashok Damani
  • 3,896
  • 4
  • 30
  • 48