0

I'm trying to access a global array inside the $.getJSON callback. For some reason I can access the array for actually calling the ajax request, but it is undefined within the callback.

JS

var toprint  = [
    {name: "Name", 
     year: "2014", 
     call: "http://api.call.com"},
     // etc.....
]


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


$.getJSON( toprint[i].call, function( data) { // toprint[i].call accessed fine
            // some code...

            // toprint[i] undefined below
            jsonPrint = "<div class='col'><h3>" + toprint[i].name + "</h3>" + toprint[i].year + "<ul>";
            // some code...
        });

}

I am getting the error:

TypeError:  toprint[i] is undefined

Which is weird, because according to other SO questions I've read I'm supposed to be able to access global variables inside AJAX callbacks.

LazerSharks
  • 3,089
  • 4
  • 42
  • 67
  • 1
    possible duplicate of [JavaScript closure inside loops – simple practical example](http://stackoverflow.com/questions/750486/javascript-closure-inside-loops-simple-practical-example) – Felix Kling Jul 17 '14 at 00:49

2 Answers2

1

When you do:

for(var i = 0; i < toprint.length; i++){
    $.getJSON( toprint[i].call, function( data) { // toprint[i].call accessed fine
        // The for loop is done and value of i === toprint.length
        // by the time this is executed
    });
}

$.getJSON is asynchronous and your for loop completes before the callback is triggered. When the loop completes, the value of i will be toprint.length. So if toprint had 3 items, the value of i will be 3 by the time the callback executes.

The callback attempts to read toprint[3] which does not exist as toprint contains just 3 items ([0], [1] and [2]). Since it does not exists toprint[3] returns undefined and trying to access .name from undefined gives you the mentioned type error.

techfoobar
  • 65,616
  • 14
  • 114
  • 135
1

You can access the global array. Your problem is your loop variable i. At the time that the callback is called i could potentially be out of bounds. In your case it is out of bounds. What you can do to fix issue is create a new variable local to your loop. var currIdx = i; and the use that variable inside of your callback function like toprint[currIdx].name. Unfortunately I have no way to test this at the moment, but I believe that if you do it this way the value of the variable currIdx will be bound to your callback function. If this doesn't work then try var currRec = toprint[i]; and use currRec.name within your callback function. I actually prefer the second method.

Jesse
  • 915
  • 1
  • 11
  • 20