Reputation: 10208
I've been looking at this problem for a few days now and I simply don't understand what I'm doing wrong. There appears to be a few problems with my code that I now simply cannot see the wood for the trees with this. I've included the code below with some comments.
(function (myPage, $, undefined) {
myPage.contextsArrays = [];
myPage.currentContextsArray = [];
myPage.getTags = function (event) {
// try to resolve tags from local variable
myPage.currentContextsArray = $.grep(myPage.contextsArrays, function (elm) { return elm.id == event.tagArea.Id; });
if (myPage.currentContextsArray.length == 0) {
$.getJSON('/exercises/getstrategycontexts/' + event.tagArea.Id, null, function (tags) {
// despite 200 response codes from the server this doesn't ever get executed …
myPage.contextsArrays.push({ id: event.tagArea.Id, items: tags });
myPage.currentContextsArray = tags;
alert(myPage.currentContextsArray);
});
}
$.get('/templates/strategycontextdc.html', function (template) {
$('#tagHost').html('');
$('#tagHostTitle').html('Tags - ' + event.tagArea.Text);
// myPage.currentContextsArray is ALWAYS [ ]
$.each(myPage.currentContextsArray, function (i, tag) {
var html = Mustache.to_html(template, tag);
$('#tagHost').append(html);
});
});
};
}(window.myPage = window.myPage || {}, jQuery));
What I'm trying to do here is some basic caching of values in a local variable. The tags are used in the UI to provide the user with a method of adding a score against a value.
I only ever want to request a collection of tags from the server if they haven't already been requested and stored in the local variable.
What I'm not understanding is that the $.getJSON() is executed (a request is made and a 200 code received along with the data) but the callback function is never executed so my collections of tags are never stored in the array for later retrieval nor set in the variable of current tags for use immediately in the UI (and therefore also consequently can never be resolved if re-requested).
I've used this jQuery command a lot and I cannot see why this isn't ever executed in this scenario. I can't see the problem with the code basically.
I've tried everything I can think of (I'm still very new to JS really) and I've exhausted my knowledge on why this code simply doesn't behave as expected.
Upvotes: 1
Views: 139
Reputation: 11822
You need to make sure your AJAX calls' callbacks fire in the correct order (as one of them relies on the other's result). You could use the jqXHR
-object's promise
-interface for that:
(function (myPage, $, undefined) {
myPage.contextsArrays = [];
myPage.currentContextsArray = [];
myPage.getTags = function (event) {
// try to resolve tags from local variable
myPage.currentContextsArray = $.grep(myPage.contextsArrays, function (elm) { return elm.id == event.tagArea.Id; });
var dfd; //this is where we'll store either the AJAX call's promise when we need to wait for the AJAX call to finish or simply store true if we don't
if (!myPage.currentContextsArray.length) {
dfd = $.getJSON('/exercises/getstrategycontexts/' + event.tagArea.Id, null, function (tags) {
// despite 200 response codes from the server this doesn't ever get executed …
myPage.contextsArrays.push({ id: event.tagArea.Id, items: tags });
myPage.currentContextsArray = tags;
alert(myPage.currentContextsArray);
}).promise();
} else {
dfd = true;
}
$.when(dfd).then(function(){ // $.when will either wait for the passed promise's resolve or immediately execute the function passed to then() when passed true
$.get('/templates/strategycontextdc.html', function (template) {
$('#tagHost').html('');
$('#tagHostTitle').html('Tags - ' + event.tagArea.Text);
// myPage.currentContextsArray is ALWAYS [ ]
$.each(myPage.currentContextsArray, function (i, tag) {
var html = Mustache.to_html(template, tag);
$('#tagHost').append(html);
});
});
});
};
}(window.myPage = window.myPage || {}, jQuery));
Read more about promise()
Upvotes: 1