I have a jQuery/JavaSCript function:
function CheckPostcode() {
// if checkbox is checked then hide and return true
// if checkbox is not checked (visible or not) then check postcode is known via Ajax call
// if not known then display the checkbox and return false
//
if ($('#perinatalWomanView_AcceptUnknownPostcode').is(':checked')) {
$("#AcceptUnknownPostcode").hide();
return true;
}
$.getJSON('@Url.Action("PostcodeCheck", "AjaxValidation", new { area = "" })', { postcode: $('#perinatalWomanView_Postcode').val() }, function (result) {
if (result.postcodeFound == true) { // executes SECOND
$("#AcceptUnknownPostcode").hide();
return true;
}
$("#AcceptUnknownPostcode").show();
return false;
});
return false; // executes FIRST
} //CheckPostcode
that seems to be correct however the AJAX getJSON response is working out of sequence (I used Firebug and alerts separately to check this). I have annotated the code to show the sequence of execution. The Ajax call executes correctly.
What am I missing – thanks.
That’s normal behavior
This is normal behavior because AJAX is inherently asynchronous, that’s what the A in AJAX stands for.
This means that requesting stuff from external resources (the server) will be worked in parallel and when results are received you can process them but you can’t count on them worked in a sequence.
Bad fix
There is a simple (and bad) fix for sequential minded people: make the AJAX call Synchronous.
$.getJSONis equal to$.ajaxit just has some predefined parameters; one of the parameters that$.ajaxaccepts isasyncwhich is by default true, replace your$.getJSONcall with an equivalent$.ajaxcall just add theasync: falseparameter.BTW.: jQuery has deprecated this parameter, I’m not all that up-to-date with the current jQuery release but it may already be removed from the API.
Good easy fix
Otherwise (recommended) learn about event driven environments. They don’t rely on things being sequential but they provide
callbackfunctions to be executed at the moment the event is triggered – This means that the data you need to process is not available at the moment of declaration but at a later moment.If you declare a
callbackfor aclick/hover/focusevent jQuery keeps thecallbackstored somewhere and only executes it when (and if) the event is triggered. It does not execute it right away and if you don’tclick/hover/focusanything it doesn’t execute it at all.It’s the same thing with AJAX, you give jQuery a callback function to be run right after the server finished transferring the response.
BTW.: This fix is not architecturally easy to use everywhere, it works if there’s only one layer of processing over that data, if there are more and logic is involved it’ll get messy.
Better more complex fix
This should set you on the straight and narrow, never to stray from it again.
You can create your own events named whatever you like. Attach an event handler to be executed when that event is triggered.
The you just tell the AJAX request to trigger that event and pass the event variables along. The event handler you already setup will be called and the rest is poetry.
If you look at the trigger function you’ll see that you can define some extra parameters to be sent to the event handlers.
If you look at the structure of an event object it contains event.type – name of the event, event.target – object that triggered it, event.data – the data that trigger passed on, and many other useful (or not) info.
Possibly best fix
There are some newer features that I haven’t read about yet (not in depth) and as far as i’ve understood them they offer an infrastructure for applying operations to some information that is not yet available which operations will be applied sometime after the data becomes available.
http://api.jquery.com/category/deferred-object/
I can’t explain this since I haven’t used it and have no understanding of it other than the possibly wrong explanation above. If anyone has the gist of this please enlighten us all.