Merging $ .get and $ .ready
To put it simply, I have an ajax call that sometimes completes before the page loads, so I tried to wrap the callback in $( fn )
, but the callback doesn't fire if the page is loaded ... Anyone have a good solution to this?
$.get( '/foo.json', function( data ){
$( function(){
// won't get here if page ready beats the ajax call
// process data
$( '.someDiv' ).append( someData );
} );
} );
And yes, I know that if I were to reverse the order of those that it always worked, but then my ajax calls would be irresponsibly delayed until the document was ready.
source to share
No, functions that are added to onDOMready will always execute and will execute immediately if the event has already occurred. See the docs at http://api.jquery.com/ready/ : only if you use $(document).bind("ready")
it will fail when the event has already been fired.
A possible reason for inactive event handlers is other handlers that throw the error. jQuery has an internal array for the handlers to execute, and the method that handles the original DOM load event just iterates over it. If one of the early handlers raises an error, the loop is aborted and no other handlers added after that will be called.
source to share
var result;
$(document).on('ready.specialAjax', function () {
if (result) {
$(".someDiv").append(result);
}
});
$.get('/foo.json').done(function (data) {
if ($(".someDiv").length) {
$(".someDiv").append(data);
$(document).off('ready.specialAjax');
}
else {
result = data;
}
});
Essentially ajax will try to add to some Div immediately if possible. Otherwise, it stores the ajax result in result
and document.ready
adds it on its own when it runs. .off
is executed to prevent concurrent data addition if ajax succeeds. It doesn't matter as the result will be empty in this case, but just to be clean.
source to share
Here's another method using deferred. Apparently you can use deferred s document.ready
, this is a bit weird:
$(document).data("readyDeferred", $.Deferred()).ready(function() {
$(document).data("readyDeferred").resolve();
});
var jqxhr = $.get('/foo.json');
$.when(jqxhr, $(document).data('readyDeferred'))
.done(function (jqxhr) {
$(".someDiv").append(jqxhr[2].responseText);
});
source to share
Load the results into a global variable and load them into DOM-ready. The key is, if the results are empty, repeat with setTimeout
until they are.
var result;
$.get("/foo.json", function(data) {
result = data;
});
function insertAJAX() {
if(result !== undefined) {
$(".someDiv").append(result);
} else {
setTimeout(insertAJAX, 250);
}
}
$(function() {
insertAJAX();
});
Note. You can add a timeout counter to stop trying after a certain amount of time if your AJAX never returns results for whatever reason.
source to share
You will need to check if the dom is ready inside the AJAX callback to make sure you add it after completion or right away. see below code,
var isDomReady = false;
$.get( '/foo.json', function( data ){
if (isDomReady) {
$(function(){ $('.someDiv').append( someData ); });
} else {
$('.someDiv').append( someData );
}
} );
$(function(){
isDomReady = true;
// and all you ready code
});
source to share