I have a number of div elements that need to be populated with text from a number of different json files. Each div has a unique id. There are two lists used to initiate the updating of the div elements, a list of unique id's and a list of the corresponding json files:
$(document).ready(function () {
var idlist = ['id1', 'id2', 'id3', 'id4'];
var fnlist = ['fn1', 'fn2', 'fn3', 'fn4'];
var info;
for (info in idlist) {
var file = fnlist[info]+'.json';
var jsonData = $('#'+idlist[info]);
$.getJSON(file, function (data) {
var pic = [data.title, data.desc];
jsonData.empty();
if (pic.length) {
var content = pic.join('<br>');
var list = $('<p />').html(content);
jsonData.append(list);
}
});
}
});
In this example four getJSON requests are fired off and return asynchronously, but in the callback function the jsonData variable is wrong (the for loop ended) and usually points to the last id in the list. Turning async off would cure this problem, but that's a bad idea and is deprecated.
My question is how to tie the returning callbacks to the original div ids so I can update the proper elements. Usually a callback has some user supplied or system supplied information about the element or window being worked on, but here it seems that the only item returned to the callback is the retrieved JSON object (that has no id information in it). I didn't see any way to supply the callback with extra information.
UPDATE
The suggested duplicate reference has a mere 29 answers and no less than three updated answers. It does, however, address the problem and is an encyclopedia of javascript scope. Here is my updated code which seems to work and resolve the problem. I hope I have constructed this correctly:
$(document).ready(function () {
var idlist = ['id1', 'id2', 'id3', 'id4'];
var fnlist = ['fn1', 'fn2', 'fn3', 'fn4'];
idlist.forEach(function(uniqueId, i) {
var file = fnlist[i]+'.json';
var jsonData = $('#'+uniqueId);
$.getJSON(file, function (data) {
console.log(data);
var pic = [data.title, data.desc];
jsonData.empty();
if (pic.length) {
var content = pic.join('<br>');
var list = $('<p />').html(content);
jsonData.append(list);
}
});
});
});
The .forEach was one of the suggestions in the referenced post and is the key change to solve the scoping problem (and gets rid of the for--in issue).