0

The code below is supposed to loop through several webpages, each one determined by the value of i, and the console.log(url); line should list every URL from those webpages. Instead, the code only lists the URLs when "i" is on its final iteration (i=0) and thus it only retrieves URL's from the final webpage it requests (http://fakeURL.com/0) - the number at the end of the URL represents "i".

How can I make the console list URL's from all iterations (when i = 45, 30, 15, and 0) instead of only the final iteration (when i = 0)?

for(i = 45; i >= 0; i -= 15) 
{
    var xhrs = new XMLHttpRequest();                                    
    xhrs.open("get", 'http://fakeURL.com/' + i, true);
    xhrs.onload = function()
    {       
            var doc2 = xhrs.response;
            $(doc2).find('a').each(function()
            {   

                var url = $(this).attr('href');
                console.log(url);

            });

    }
    xhrs.responseType = 'document';
    xhrs.send();
}

EDIT: Below is my actual source code (unsimplified) after doing what Teemu suggested. Now 'i' is always -15 for every request the for-loop makes with the XMLHttpRequest:

var url;
var title;
function ajaxCall (x, y)
{
    setTimeout(function ()
    {
        var xhrs = new XMLHttpRequest();                                    
        xhrs.open("get", 'http://fakeURL.com/' + i, true);
        xhrs.onload = function()
        {       
            var doc2 = xhrs.response;
            $(doc2).find('a').each(function()
            {                                           
                var x = $(this).attr('href');
                var y = $(this).text();

                console.log(x);
                console.log(y);
            });

        }
        xhrs.responseType = 'document';
        xhrs.send();
    }, Math.random() * 1000 + 1000);
}

for(i = 45; i >= 0; i -= 15) 
{   
    ajaxCall(url, title);
}

Any idea why 'i' is always -15?

EDIT 2: I didn't follow Teemu's solution correctly in the code above. Here is the fixed version for future reference:

var i;
function ajaxCall (x)
{
        var xhrs = new XMLHttpRequest();                                    
        xhrs.open("get", 'http://fakeURL.com/' + x, true);
        xhrs.onload = function()
        {       
            var doc2 = xhrs.response;
            $(doc2).find('a').each(function()
            {                                           
                var url = $(this).attr('href');
                var title = $(this).text();

                console.log(url);
                console.log(title);
            });

        }
        xhrs.responseType = 'document';
        xhrs.send();
}

for(i = 45; i >= 0; i -= 15) 
{   
    ajaxCall(i);
}
Swift
  • 54
  • 1
  • 8
  • Put the AJAX call to a function, and pass `i` within a function call. – Teemu Oct 05 '14 at 18:04
  • @Teemu I'm not sure how to do that. Do I include everything from `xhrs.open` to `xhrs.send` in a function? Also, how do I implement the function call and pass `i` within it. I'm really new to coding, sorry. – Swift Oct 05 '14 at 18:18
  • Probably the problem is that you are using an asynchronous call (`doAsync` (third) parameter of `xhrs.open()` has been set to `true`), so the loop goes into the next iteration and overwrites the content of `xhrs` before the current request is complete... Try changing third parameter of `xhrs.open()` to `false`. – Janaka Bandara Oct 05 '14 at 18:23
  • @Farad As simple as [this](http://jsfiddle.net/s5tb8b66/) ... – Teemu Oct 05 '14 at 18:26
  • @JanakaBandara Bad practice, that ruins the idea of AJAX. – Teemu Oct 05 '14 at 18:34
  • @Teemu Thanks for pointing that out :) Didn't think about it! – Janaka Bandara Oct 05 '14 at 18:45
  • @Teemu I tried your solution and ran into another problem. `i` always shows up as negative 15. I posted my new code in the question. – Swift Oct 05 '14 at 20:01
  • Ehh... `setTimeout` in my example is just emulating the `onload` handler in your AJAX call. Remove the timer from your code. Secondly, you're not passing `i` to `ajaxCall`, you're just passing some global variables. The idea is to pass `i` to the function, where it, as an argument, becomes a local variable in that function (passed by value). `onload` handler has access to the outer scope, and can read the argument. – Teemu Oct 05 '14 at 20:46

0 Answers0