I am familiar with the nuances of async javascript calls. All work with data returned from an async call must be done in the callback. Roger that.
In the following code, my .ajax()
call retrieves a serialised list of crew members from a C# generic handler, and the callback contains a .get()
(which is also async), that retrieves a template and merges each crew member's data with the html template, and injects it into the page.
All that works fine, however, at the end, every iteration through the loop finishes and every panel inserted on the page contains only data from the last crew member in the list.
So, I end up with ALL panels on the page being for the same person. The last person in the list.
The .get()
is being issued from within the callback of the .ajax()
. The work is being performed in the .done()
callback of the inner .get()
.
This should be safe, I thought. The work is being done in the callback of the .ajax()
call, and the work with that data is being performed in the .done()
callback of the .get()
.
What happens is that the loop fires all "1 to n" times. And THEN the .done()
call back fires "1 to n" times.
I suspect that even though the .get()
is called inside a for loop, the for loop is not async, and there's a problem in that somewhere.
$.ajax({
type: "POST",
url: "js/handlers/LoadCrew.ashx",
dataType: "text",
cache: false,
success: function (ajaxResult) {
var crew = JSON.parse(ajaxResult);
for (var i = 0; i < crew.length; i++) {
var thisCrewMember = crew[i];
debugger;
var getScript = $.get({
url: "templates/CrewPanel.html",
dataType: "text",
data: thisCrewMember
})
.done(function (template) {
debugger;
template = template.replace("[[NAME]]", thisCrewMember.NAME);
document.getElementById("CrewPanels").innerHTML += template;
})
.fail(function () {
alert("Failed to retrieve template: CrewPanel.html");
})
}
},
error: function (result) {
return false;
}
});
Can someone tell me if what I am trying to do is even possible, and if so, how?
Edit
Added the two debugger statements to the code listing.
I'm not sure this is a scoping issue. At execution time, in the Chrome debugger, (assume 8 rows of JSON data from the generic handler), it will break 8 times on the first debugger statement, THEN it will break 8 times on the second debugger statement in the done() callback.
When it does this, of course, the for loop has finished it's iterations and thisCrewMember is sitting on the last value assigned.
Thanks for the comments, but I think this is an async issue, even though I'm doing the work in the callback functions. If not, can someone explain how scoping is the issue?
Edit 2
I take it back. Changing var
to const
as PaulPro suggested does indeed fix things. I guess I do not understand how thisCrewMember is scoped. But the suggested change has resulted in better results.