Reputation: 1116
I have the function shown below, it just makes a request to a bunch of endpoints housed in an array. Right now I have the Ajax calls be sync (as opposed to the native async).
This is because although when async it does cycle through the urls and makes the calls correctly, the name of the API, which I set to the variable 'name', will only display the last name in the list:
When it should display like this (which it does only if I set the Ajax call to sync):
I'm pretty sure this is due to the fact that the threads from the ajax calls can take any given time to complete while the for loop has finished its iterations way before, thus having only the las name in the list for display.
How can I keep the calls async while also having the names synched to the response of each call?
Thanks.
function isAlive(service) {
var buildIsAliveBox = function (isAlive, name, xhr) {
var isAliveOuterCnt = $('#isAliveOuterCont' + service);
var applyClass = isAlive ? 'alive' : 'dead';
var status = xhr.status == 0 ? 'Failed' : xhr.status;
var xhrMessage = handleHttpResponse(xhr);
var isAliveBox = $('<div class="' + applyClass + ' isAliveBox" class="btn btn-secondary" data-toggle="tooltip" data-placement="bottom" title="' + xhrMessage + '"><p class="svrName">' + name + '</br>' + status + '</p></div>');
isAliveOuterCnt.append(isAliveBox);
};
var svce = service.toLowerCase();
for (var i = 0; i < environments.qa[svce].healthUrls.length; i++) {
var data = environments[envSwitch][svce].healthUrls[i];
var name = data.split(',')[0];
var url = data.split(',')[1];
$.ajax({
url: url,
type: 'GET',
async: false,
headers: {
'Access-Control-Allow-Origin': '*',
'Content-Type': 'application/json',
},
success: function (data, status, xhr) {
buildIsAliveBox(true, name, xhr);
},
fail: function (xhr, textStatus, errorThrown) {
buildIsAliveBox(false, name, xhr);
},
error: function (xhr, status, err) {
buildIsAliveBox(false, name, xhr);
}
});
}
}
Upvotes: 0
Views: 392
Reputation: 29012
Change var
to let
, at least for name
(but ideally for the other variables as well to avoid stumbling upon this issue again later on).
var
is function-scoped and not block-scoped and hence the same data
, name
and url
variables are reused every iteration. And the response from the AJAX call comes back long after your loop finished running, so by that time those variables will have the values they last got assigned (in the last iteration of the loop).
With let
you get a new scope for every iteration so each AJAX call will get a different name
variable etc. it accesses in the callback.
Upvotes: 2