Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AJAX call in for loop won't return values to correct array positions

I need to get a range of pages using AJAX and put them into an array, where their given place in the array is equal to the i of a for loop (it's a caching-like function for blog pages, and the range of the for loop is entirely variable). I'm doing something akin to the following:

var bongo = new Array();

for (i = 0; i < 10; i++) {

    jQuery.ajax({ type: "GET", url: 'http://localhost', data: queryString, success: function(request) { bongo[i] = request } })

}

The problem is, that unless I add async: false to the .ajax options (which would make it... SJAX?), which causes the requests to basically pause the browser, going against what I'm trying to do, the i in the success callback will always end up being 11, whereas I of course want it to pour the returned data into each slot of the array from 0 to 10.

I've tried replacing the line with this:

bongo[i] = jQuery.ajax({ type: "GET", url: 'http://localhost', data: queryString }).responseText

But that made no difference.

like image 475
Heilemann Avatar asked Mar 08 '10 21:03

Heilemann


People also ask

What does an ajax call return?

ajax() returns the XMLHttpRequest object. As of jQuery v1.

How do you write if condition in ajax success?

ajax({ url: $(this). attr('href'), type: $(this). attr('method'), dataType: 'json', success: function (data) { //PROBLEM HERE ********** if(data. success == 'true' ){ alert('true'); } else { alert('false') }; ;} });

Does ajax return a promise?

ajax returns, which is a jqXHR object that conforms to the promise interface. If there is a failure, the outer fail function is invoked. The outer fail function is also invoked if the processData function fails. When both the getData and processData functions are successful, the outer done method is invoked.

What triggers ajax success?

Whenever an Ajax request completes successfully, jQuery triggers the ajaxSuccess event. Any and all handlers that have been registered with the . ajaxSuccess() method are executed at this time. $( ".


1 Answers

You need a closure:

var bongo = [];
for (i = 0; i < 10; i++)
{

  (function(i)
    {
      jQuery.ajax(
        {
          type: "GET",
          url: "http://localhost",
          data: queryString,
          success: function(request) { bongo[i] = request } 
        });  
    })(i);
}

Loops are the #1 place where inline functions stump people. The bongo[i] = result isn't called until later. The value of i at that time is different (most likely 11). If you want to "trap" or "capture" the current value of i, you need to create a new scope. The only way to do that in javascript is with another function.

like image 143
Plynx Avatar answered Oct 05 '22 14:10

Plynx