Reputation: 478
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
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
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:
within the while loop of the success function:
Now your myList looks like second,first,third
just a bit of thought for the rest of your script.
Upvotes: 1
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