javascriptjsonajax

JS / AJAX / JSON


I'm new to JS / AJAX and JSON parsing. I've been trying to debug this code snippet for a while now and I can't seem to figure it out.

I'm trying to append the values to dynamic divs but the $("#" + id) inside the AJAX request always has the last value of the id inside the for loop. It's not appending it every time the for loop increments to the next value of the div id.

Anyone know what is wrong? or are AJAX requests like this?

The var myID at the end was for debugging. The myID gets the value of the id fine but the AJAX request doesn't seem to execute until the last value of the for loop is running.

Any help would be appreciated.

    for (var x = 0; x < days.length; x++) {
            var y = days[x];
            var id = location + "_day_" + y;
            $("#" + location).append("<div id='" + id + "'><h2>Day #" + y + "</h2></div>");

            $.ajax
            ({
                type: "GET",
                url: jsonFile,
                dataType: "json",
                success: function(json) {

                    for (var i = 0; i < json.trips.length; i++) {
                        var name = json.trips[i].name;
                        var cost = json.trips[i].cost;

                        radioButton = "<label><input type='radio' name='day_" + y + "' />" + name + " - $" + cost + ".00</label><br>";
                        $("#" + id).append(radioButton);
                    }
                }
            });
            var myID = id;
    }

Solution

  • That is because the Ajax callback doesn't get called until later (after the request finished) and by that time the value of id will be the last value in the loop. You need to use a closure to solve this problem:

    {
       type: "GET",
       url: jsonFile,
       dataType: "json",
       success: (function(id){
                return function(json) {
    
                    for (var i = 0; i < json.trips.length; i++) {
                        var name = json.trips[i].name;
                        var cost = json.trips[i].cost;
    
                        radioButton = "<label><input type='radio' name='day_" + y + "' />" + name + " - $" + cost + ".00</label><br>";
                        $("#" + id).append(radioButton);
                    }
                };
            })(id)
    }
    

    Now the function gets passed id as a local variable, instead of using the variable in the outer scope which has changed since you made this function.

    To help you understand, here is an example of what is happening to you: http://jsfiddle.net/qXCKZ/ Notice how the new value of id is alerted.

    Here is the solution which creates a local copy of the variable by using a closure: http://jsfiddle.net/DAwNz/