31

I have a for loop enclosing an ajax call and I'm trying to determine the best method for passing the index from the for loop to the callback function. Here is my code:

var arr = [2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010];

for (var i = 0; i < arr.length; i++)
{
  $.ajaxSetup({ cache:false })
  $.getJSON("NatGeo.jsp", { ZipCode: arr[i], Radius:   
            document.getElementById("radius").value, sensor: false },      
            function(data)
            { 
              DrawZip(data, arr[i]);
        }
  );
}

Currently, only the last value of the arr array is passed due to the asynchronous ajax call. How can I pass each iteration of the arr array to the callback function, aside from running the ajax call synchronously?

1
  • 2
    although this is a duplicate of about 30 other questions, it is a very common issue when using functions within loops, and I hope you won't mind me modifying one of the tags to push that count up to 31 :) Commented May 20, 2011 at 20:50

3 Answers 3

70

You could use a javascript closure:

for (var i = 0; i < arr.length; i++) {
  (function(i) {
    // do your stuff here
  })(i);
}

Or you could just use $.each:

var arr = [2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010];

$.each(arr, function(index, value) {
  $.ajaxSetup({ cache:false });
  $.getJSON("NatGeo.jsp", { ZipCode: value, Radius:   
    document.getElementById("radius").value, sensor: false },      
    function(data) { 
      DrawZip(data, value);
    }
  );
});
Sign up to request clarification or add additional context in comments.

1 Comment

It's worth nothing that these two solutions are the same, and there is nothing magical about $.each. In both cases an anonymous function was used to create a closure.
5

I didn't read all 30 questions @Anurag listed, but I found the following callback syntax that seems to work:

(function(year) {
  return (function(data) {DrawZip(data, year);});
})(arr[i])

This replaces the original function(data). Incidentally, the results are in random order, due to the asynchronous response

Comments

3

You can even omit for-loop brackets as mentioned by John Resig here i think this way is more readable

for (var i = 0; i < arr.length; i++) (function(i) {

    // async processing
    setTimeout(function(){ 
      console.log(i);
    }, i * 200); 

})(i);

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.