0

I am looping through an array of urls. Each one fetches some jsonp data from a different domain. The success handler needs to be able to access the data in the original loop, however when called from the callback it is always the last value and not the value that was set when the ajax function was called. How do I access or pass this value to the callback?

for(var site in data.sites){
    var domain =  data.sites[site].domain;
    $('#site-logout').append('<div class="processing" id="' + domain.replace(".","-") + '"><strong>' + domain + '</strong> is logging out.');
    $.getJSON(url, function(data){
        if(data.success == true)
            $("#" +  domain.replace(".","-")).removeClass("processing").addClass("processed").html('<strong>' + domain + '</strong> has logged out.');
        else
            $("#" +  site.domain.replace(".","-")).removeClass("processing").addClass("error").text('<strong><a href="http://' + domain + '">' + domain + '</a></strong> has failed to log out. Follow the link to try manually.');
    });
}

1 Answer 1

5

In JavaScript there's no block scope for your for loop, the domain variable is shared for all loops, it's scoped to the parent function, not strictly inside the loop (for example you could access it after the closing } for the for() and it'd be the value it had in the last loop).

To resolve this, you need to create an additional scope with it's own variable; using $.each() is easiest in this case:

$.each(data.sites, function(i, site){
  var domain = site.domain;
  $('#site-logout').append('<div class="processing" id="' + domain.replace(".","-") + '"><strong>' + domain + '</strong> is logging out.');
  $.getJSON(url, function(data){
    if(data.success == true)
        $("#" + domain.replace(".","-")).removeClass("processing").addClass("processed").html('<strong>' + domain + '</strong> has logged out.');
    else
        $("#" + domain.replace(".","-")).removeClass("processing").addClass("error").text('<strong><a href="http://' + domain + '">' + domain + '</a></strong> has failed to log out. Follow the link to try manually.');
  });
});

The for loop way would be like this:

for(var site in data.sites){
  (function(domain) {
    $('#site-logout').append('<div class="processing" id="' + domain.replace(".","-") + '"><strong>' + domain + '</strong> is logging out.');
    $.getJSON(url, function(data){
        if(data.success == true)
            $("#" +  domain.replace(".","-")).removeClass("processing").addClass("processed").html('<strong>' + domain + '</strong> has logged out.');
        else
            $("#" + domain.replace(".","-")).removeClass("processing").addClass("error").text('<strong><a href="http://' + domain + '">' + domain + '</a></strong> has failed to log out. Follow the link to try manually.');
    });
  })(data.sites[site].domain);
}
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.