Reputation: 30
I am trying to paginate through a website, where in order to request the next page, the information on the current page is required.
function paginateSite(numPages, cb) {
var stringToGetToNextPage = ''
for (var i = 0; i < numPages; i++) {
(function(i, stringToGetToNextPage) {
request({
url: 'http://website.com',
qs: {
nextPage: stringToGetToNextPage
}
},
function(err, res, body) {
body_json = JSON.parse(body)
console.log(body_json.stringToGetToNextPage)
})
})(i, stringToGetToNextPage)
}
}
As you can see there is no way for me to set stringToGetToNextPage outside of the anonymous function. I have looked through the async library documentation but couldn't find anything that solved my problem.
Has anybody ran into this problem? It seems like this is a case where the async paradigm doesn't have a clean solution.
EDIT: QUESTION #2, is there conceivably a way to do this without recursion? Recursion is fine for small examples, but now I have a stackoverflow case that can kill the program without warning (and eats up memory).
Upvotes: 0
Views: 45
Reputation: 101690
Recursion is the way to do this.
First, factor out a function to retrieve a single page:
function requestPage(stringToGetToNextPage, callback) {
request({
url: 'http://website.com',
qs: {
nextPage: stringToGetToNextPage
}
}, function(err, res, body) {
if (err) { callback(err); }
else { callback(null, JSON.parse(body)); }
});
}
Then, make a function that can recursively call itself to get each successive page:
function requestAllPages(stringToGetToNextPage, callback) {
requestPage(stringToGetToNextPage, function (err, page) {
if (err) { callback(err); }
else if (page && page.stringToGetToNextPage) {
requestAllPages(page.stringToGetToNextPage, callback);
}
else { callback(); }
});
}
Then kick it all off:
requestAllPages(null, function () {
console.log('Done!');
});
Edit If you really do want to paginate a specific number of pages rather than going to the end, you can accomplish that with a small modification to requestAllPages
:
function requestPages(numPages, stringToGetToNextPage, callback) {
if (numPages <= 0) { callback(); return; }
requestPage(stringToGetToNextPage, function (err, page) {
if (err) { callback(err); }
else if (page && page.stringToGetToNextPage) {
requestPages(numPages - 1, page.stringToGetToNextPage, callback);
}
else { callback(); }
});
}
requestPages(20, null, function () {
console.log('Done!');
});
Upvotes: 1
Reputation: 943569
Write a recursive function.
function get_page(next_page_number, last_page_number, string_needed, callback) {
request(
{
url: 'http://website.com',
qs: {
nextPage: string_needed
}
},
function(err, res, body) {
// NB: Bad variable name. `body` is JSON. `body_json` won't be.
var body_json = JSON.parse(body);
if (next_page_number == last_page_number) {
callback(body_json);
} else {
get_page(
next_page_number + 1,
last_page_number,
body_json.stringToGetToNextPage,
callback
);
}
}
);
}
get_page(1, 27, "", function (body_json) { console.log(body_json); });
Upvotes: 1