Fat Monk Fat Monk - 22 days ago 7
Ajax Question

Accessing an array from with an AJAX callback function

I'm trying to use an AJAX call to update a bunch of image elements on a page. The list of elements to update is held in an array and the URLs to assign to each image are retrieved from a PHP page via AJAX.

The code I have below doesn't work because

imagesArray[i]
is undefined when it is called from the callback function in the AJAX call - due to the asynchronous nature of JavaScript presumably.

var imagesArray = document.getElementsByClassName('swappableImages');

for (i = 0; i < imagesArray.length; i++) {
var requestUrl = "http://example.com/getAnImageURL.php";

getDataViaAJAX(requestUrl, function(data) {
alert('img url=' + data.responseText);
imagesArray[i].src = data.responseText;
});
}

function getDataViaAJAX(url, callback) {
var request = window.ActiveXObject ?
new ActiveXObject('Microsoft.XMLHTTP') :
new XMLHttpRequest;

request.onreadystatechange = function() {
if (request.readyState == 4) {
request.onreadystatechange = doNothing;
callback(request, request.status);
}
};
request.open('GET', url, true);
request.send(null);
}

function doNothing() {}


On reading around it seems that one way to solve this would be to use a
closure
, however closures are something I've still not managed to get my head around and the examples I have found have just confused me further.

So, how can I update each element in the array as an when the AJAX function returns?




Note that the 'duplicate' question that has been identified is a jQuery version of the question with jQuery specific answers. I am using vanilla JavaScript.

Answer

Note: First example/approach - referred to in comments - removed from answer.

You may try this:

var requestUrl = "http://example.com/getAnImageURL.php";

for (i = 0; i < imagesArray.length; i++) {
  (function(j) {
    getDataViaAJAX(requestUrl, function(data) {
      alert('img url=' + data.responseText);
      imagesArray[j].src = data.responseText;
    });
  })(i);
}