JQuery/Ajax calls in a For Loop

ajax, javascript, jquery

Solution

if you loop looks something like this:

for(var i=0; i<10; i++){
   $.ajax({
    //
    success:function(data){
       $("#p" + i + "_points").html(data);
    }
   });
}

it will not work as `i` will end up being the last `i` value in the loop; You need something like below

for(var i=0; i<10; i++){
   (function(index){
      $.ajax({
       //
       success:function(data){
          $("#p" + index + "_points").html(data);
       }
      });
   })(i);
}

The closure along with the passing of `i` will keep number value for that call.

of course there will need to exist elements with ids 1-10 or whatever number you use so:

<element id="p1_points">
<element id="p2_points">
<element id="p3_points">
...

EDIT to account for JSONP callback:

modify myCallback() to be:

function myCallback(data,index)

and use the index to make your `"#p"+index+"_points"` etc ids

and then for the loop and ajax:

//Keeps track of the callbacks
//we will prepend 'jsonpCallbacks.' to the callback names
window.jsonpCallbacks = {};

for (var i = 0; i < thisweeksraiders.length; i++){
    (function(index){
      window.jsonpCallbacks["myCallback"+index] = function(data){
         myCallback(data,index);
      };
    })(i);
    $.ajax({
        "url":"http://us.battle.net/api/wow/character/aerie-peak/" + thisweeksraiders[i] + "?jsonp=jsonpCallbacks.myCallback"+i,
        "type":"GET",
        "data": { fields: "items, professions, talents, progression"},
        "dataType":"jsonp",
        "contentType":"application/json",
        "jsonpCallback":"jsonpCallbacks.myCallback"+i,
        "success":function(data1){
        }
    })
}

Problem

Is it possible to put `("xxxxx").html(data)` in a for loop where the "xxxx" variable changes each time? I honestly feel like I've tried everything. I'm trying to fill up an HTML table with JSONP data from a looping ajax call where the URL changes each time. The same callback function is used every time, but, obviously, I keep overwriting the data that is to be sent to the HTML table tags because I can't figure out a way to dynamically change these variables. Basically, I want the first time the callback function is called to store data in something like... ``` $("#p1_points").html(data_from_ajax_call) ``` The second time I want it to do... ``` $("#p2_points").html(data_from_ajax_call) ``` I've tried silly things like (inside a for loop) doing ... ``` $("#p" + i + "_points").html(data_from_ajax_call) ``` and all sorts of fun stuff, but it doesn't accept arguments of any kind... So, any thoughts? Is this trivial and I'm just over-thinking and under-sleeping it? Thanks in advance for any help. UPDATING FOR CLARITY My ajax calls look like this... ``` for (var i = 0; i < thisweeksraiders.length; i++){ $.ajax({ "url":"http://us.battle.net/api/wow/character/aerie-peak/" + thisweeksraiders[i] + "?jsonp=myCallback", "type":"GET", "data": { fields: "items, professions, talents, progression"}, "dataType":"jsonp", "contentType":"application/json", "jsonpCallback":"myCallback", "success":function(data1){ } }) } ``` and my callback function looks like this... ``` function myCallback(data1) { //itemscounter += 1; var hascloak = "No"; var possupgrades = 30; var offhandequipped = false; var tempupgrades = 0; var tierequipped = 0; for (var i = 0; i < gearlist.length; i++){ if (data1.items[(gearlist[i])].tooltipParams.upgrade) tempupgrades += data1.items[(gearlist[i])].tooltipParams.upgrade.current; } for (var i = 0; i < tierlist.length; i++){ if(data1.items[(tierlist[i])].tooltipParams.set) tierequipped += 1; } if (data1.items.offHand){ tempupgrades += data1.items.offHand.tooltipParams.upgrade.current; offhandequipped = true; } if (offhandequipped) possupgrades = 32; if(data1.items[(gearlist[3])].quality == 5) hascloak = "Yes"; $("#p1_cloak").html(hascloak); $("#p1_tier").html(tierequipped + "/5"); $("#p1_achieve").html(data1.achievementPoints); $("#p1_iLevelE").html(data1.items.averageItemLevelEquipped); $("#p1_upgrades").html(tempupgrades + "/" + possupgrades); var totalnormalkills = 0; var totalheroickills = 0; var furthestboss = null; for (var i = 0; i < soobosslist.length; i++){ totalnormalkills += data1.progression.raids[31].bosses[i].normalKills; totalheroickills += data1.progression.raids[31].bosses[i].heroicKills; } if (totalheroickills == 0){ for (var i = 14; i > 0; i--){ if (data1.progression.raids[31].bosses[i-1].normalKills > 0){ furthestboss = i + "N"; break; } } } else { for (var i = 14; i > 0; i--){ if (data1.progression.raids[31].bosses[i-1].heroicKills > 0){ furthestboss = i + "H"; break; } } } $("#p1_normalkills").html(totalnormalkills); $("#p1_heroickills").html(totalheroickills); $("#p1_xp").html(furthestboss); var classtemp; var colortemp; switch(data1.class){ case 1: classtemp = "Warrior"; colortemp = "#C79C6E"; break; case 2: classtemp = "Paladin"; colortemp = "#F58CBA"; break; case 3: classtemp = "Hunter"; colortemp = "#ABD473"; break; case 4: classtemp = "Rogue"; colortemp = "#FFF569"; break; case 5: classtemp = "Priest"; colortemp = "#FFFFFF"; break; case 6: classtemp = "Death Knight"; colortemp = "#C41F3B"; break; case 7: classtemp = "Shaman"; colortemp = "#0070DE"; break; case 8: classtemp = "Mage"; colortemp = "#69CCF0"; break; case 9: classtemp = "Warlock"; colortemp = "#9482C9"; break; case 10: classtemp = "Monk"; colortemp = "#00FF96"; break; case 11: classtemp = "Druid"; colortemp = "#FF7D0A"; break; } $("#p1_classspec").html("<font color=" + colortemp + "><b>" + data1.name + "</b></font><font size='-1' color=" + colortemp + "><em> (" + data1.talents[0].spec.name + ")</em></font>"); var profstemp = (data1.professions.primary[0].name + " & " + data1.professions.primary[1].name); $("#p1_profs").html(profstemp); } ``` So, basically, all the #p1 stuff I could put at the end of the function, but I'd like to change it all to $p2 to fill in the next row on my table. The HTML should be obvious, but here it is... ``` <body> <center> <table width="100%" border="0"> <tr> <td id="p1_classspec">&nbsp;</td> <td id="p1_iLevelE">&nbsp;</td> <td id="p1_upgrades">&nbsp;</td> <td id="p1_cloak">&nbsp;</td> <td id="p1_tier">&nbsp;</td> <td id="p1_profs">&nbsp;</td> <td id="p1_achieve">&nbsp;</td> <td id="p1_normalkills">&nbsp;</td> <td id="p1_heroickills">&nbsp;</td> <td id="p1_xp">&nbsp;</td> </tr> <tr> <td id="p2_classspec">&nbsp;</td> <td id="p2_iLevelE">&nbsp;</td> <td id="p2_upgrades">&nbsp;</td> <td id="p2_cloak">&nbsp;</td> <td id="p2_tier">&nbsp;</td> <td id="p2_profs">&nbsp;</td> <td id="p2_achieve">&nbsp;</td> <td id="p2_normalkills">&nbsp;</td> <td id="p2_heroickills">&nbsp;</td> <td id="p2_xp">&nbsp;</td> </tr> <tr> <td id="p3_classspec">&nbsp;</td> <td id="p3_iLevelE">&nbsp;</td> <td id="p3_upgrades">&nbsp;</td> <td id="p3_cloak">&nbsp;</td> <td id="p3_tier">&nbsp;</td> <td id="p3_profs">&nbsp;</td> <td id="p3_achieve">&nbsp;</td> <td id="p3_normalkills">&nbsp;</td> <td id="p3_heroickills">&nbsp;</td> <td id="p3_xp">&nbsp;</td> </tr> </table> </center> </body> ``` If you follow this link, you'll see what I'm going for (this is not using the for loop). I just want to drastically cut down on my code. http://www.mynextbit.com/Pages/Wreckedified/test2.html One more Update for Patrick... ``` $(document).ready(function(){ for (var i = 0; i < thisweeksraiders.length; i++){ (function(index) window.jsonpCallbacks["myCallback" + index] = function(data){ myCallback(data,index); }; })(i); $.ajax({ "url":"http://us.battle.net/api/wow/character/aerie-peak/" + thisweeksraiders[i] + "?jsonp=jsonpCallbacks.myCallback" + i, "type":"GET", "data": { fields: "items, professions, talents, progression"}, "dataType":"jsonp", "contentType":"application/json", "jsonpCallback":"jsonpCallbacks.myCallback"+i, "success":function(data1){ } }) } }); ```

Original source

Related problems