I’m using global variables to pass around a response from a AJAX call:
window.response = null; // most recent response from XMLHttpRequest
// the callback function for XMLHttpRequest
function userObjFromJSON() {
if (this.readyState == 4) {
var json = eval('(' + this.responseText + ')');
window.response = json;
}
else {
indicateLoading();
}
}
// loads the info for this username on the page
function loadUsernameInfo(username) {
clearPage();
getUserInfo(username);
var profile = window.response; // most recent json response (what if it hasn't come in yet?)
window.response = null;
if (profile) {
indicateLoaded(username);
fillInProfileInfo(profile);
getTweets(username);
var tweets = window.response; // most recent json response (what if it hasn't come in yet?)
if (tweets) {
fillInTweets(tweets, MAX_TWEETS);
var mentions = mentionedUsers(tweets, MAX_TWEETS);
fillInMentioned(mentions);
}
else {
indicateUnavailableTweets();
}
}
else {
indicateInvalidUsername(username);
}
}
The problem is that, by the time the controller function wants to start filling in information, the AJAX call hasn’t always returned yet. (If I step through it slowly in a debugger, it works fine.) What can I do to get around this?
I tried something like this:
getUserInfo(username);
while (window.response == null); // infinite loop here
var profile = window.response; // most recent json response
But that just makes my browser unresponsive.
I am hesitant to call the needed function from the callback, because I’m trying to implement model-view-controller. Calling a controller/view function from the model feels like it would break the pattern.
The best practice here would be to place the code you currently have in
loadUsernameInfointo the callback for the AJAX call itself, instead of relying on the global variable. That way, when your response comes back, the callback that executes, instead of just setting your window.response variable, will actually go ahead and update your UI and perform any other related tasks.Another way of doing the same thing is just to call
loadUsernameInfofrom your existing callback, like:Hope that helps!