sammy88888888
sammy88888888

Reputation: 478

Loop through paginated API javascript

I have been trying to create a function which calls a paginated API, loops though each of the pages and adds a JSON value to an array. I would like the function to return the array.

The function makes an initial call to the api and calculates the number of times it has to loop by counting the number of results returned from all the pages and divides by 10 (the number of results per page is 10). So far the function looks like this:

function loopPages(url) {
    $.getJSON(url, function (data) {
        var pages = Math.ceil(data.count/10 + 1);
        var i;
        var myList = [];
        for (i = 1; i < pages; i++) {
            $.getJSON("http://urladdress.com/?page=" + i, function (data) {
                obj = data.results;
                $.each(obj, function (k, v) {
                    myList.push(v.city_name);
                });
            return myList
            });
        }
    });
}
loopPages('http://urladdress.com/?page=1');

I cannot, however, work out where the return statement should go and how to access the array from outside the function.

I have also looked for other solutions to this problem (which I guess is rather common) but found nothing. Any help much appreciated!

Upvotes: 0

Views: 11004

Answers (3)

Sandeep Mukherjee
Sandeep Mukherjee

Reputation: 771

HTML:-

<!DOCTYPE html>
<html>
<head>
    <title>pagination</title>
    <link rel="stylesheet"  href="pathofcssfile.css">
</head>
<body>
    <div>
        <table id="user"></table>
    </div>
    <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
    <ul>
    <li value="1">1</li>
    <li value="2">2</li>
    <li value="3">3</li>
    <li value="4">4</li>
    <li value="5">5</li>
    <li value="6">6</li>
    <li value="7">7</li>
    <li value="8">8</li>
    <li value="9">9</li>
    <li value="10">10</li>

    </ul>

    <script src="pathnameofjsfile.js" type="text/javascript"></script>
</body>
</html>

JS:-

var xhr = new XMLHttpRequest();
xhr.open('GET',"https://jsonplaceholder.typicode.com/albums",true);
xhr.send();

var udata;

xhr.onload = function() 
{
    if(this.status == 200) 
    {
        var userdata = JSON.parse(this.responseText);
        console.log(userdata);
        udata = userdata;
        data(1);
    }
}

$("li").click(function ()
{       
var a = $(this).attr("value");
console.log("value li "+ a);
data(a);
});

function data(a)
{  
    var output = "";
    for(i=((a-1)*10);i<(a*10);i++)
    {
        output +='<tr>'+
                 '<td>'+ udata[i].userId + '</td>'+
                 '<td>'+ udata[i].id + '</td>'+
                 '<td>'+ udata[i].title + '</td>'+ '<br>'
                 '</tr>';
    }
    document.getElementById('user').innerHTML = output;
}

CSS:-

ul{
display: flex;
list-style-type:none;
padding: 20px;
}

li{
padding: 20px;
}

td,tr{
    padding: 12px;
}

Upvotes: -1

Greg Borbonus
Greg Borbonus

Reputation: 1384

The getJSON function is run asynchronously, so it will actually return before the job is done, thus not allowing you to do anything with the return data from the success function.

What you can do is set the myList variable to global, simply remove the var from within the function:

Change it from:

function loopPages(url) {
    $.getJSON(url, function (data) {
        var pages = Math.ceil(data.count/10 + 1);
        var i;
        var myList = [];

to:

function loopPages(url) {
    $.getJSON(url, function (data) {
        var pages = Math.ceil(data.count/10 + 1);
        var i;
         myList = [];

I would also suggest making pages global doing the same thing.

You can remove the return statement entirely.

I'd also suggest NOT doing multiple ajax calls within the function, this can make it so that myList may get out of order, because a the ajax call may finish too early.

so think on it like this:

  • loopPages run...
  • return back to js to run everything else.
  • loopPages ajax finishes, run the success function.

within the while loop of the success function:

  1. first ajax
  2. second ajax
  3. third ajax
  4. second ajax returns
  5. first ajax returns
  6. third ajax returns

Now your myList looks like second,first,third

just a bit of thought for the rest of your script.

Upvotes: 1

meskobalazs
meskobalazs

Reputation: 16041

The $.getJSON method is asynchronous, so you need to use a callback to use the data you get as the result. The skeleton code is like this:

function loopPages(url, callback) {
    // ...
        $.getJSON("...", function (data) {
            // ...
            callback(myList);
        });
});

So you just need to define the callback similarly:

function callback(myList) {
    // fill your data grid
}

Now, the loopPages function can be used like this:

loopPages('http://urladdress.com/?page=1', function (myList) {
    // fill your data grid
});

PS: after this, it should be clear, that this is really quite a duplicate...

Upvotes: 3

Related Questions