I have a service that is written in Node and sends the request to get a list of teams for a specific city to another API service.
Request params:
city
page
per_page
Response body:
page
per_page
more
teams
per_page
by default is set to 1000 but the number of teams is much greater than 1000 and some teams are not returned in the response. I need all the teams though.
For some reasons I am not going to specify here, I do not want to change per_page
param, but what I want to do is to send the first request and check if more
in the response body is true
(meaning there are more teams), I extract teams from the response body and add it to the final result, increase page
param and send the request with params:
{
"page": "2",
"city": "chicago",
"per_page": 1000,
}
I keep doing that until more
header is false
.
The service is written in Node and I use the request
package for sending HTTP requests. Initially, I wanted to use while loop
:
function teamsInCity(city, page, result, callback) {
let more = true;
while(more) {
// send the request
// extract teams into the result array
// check if there is more
// send another request
// keep sending requests and appending teams until more is false
}
// return the final result with all the teams
}
But that didn't work because while loop
sends the request and keeps executing the next line of code without waiting for the response. So I solved it with recursion and it works. But I need it to be tail call optimized and I am not sure but I think Node doesn't support that but I might be wrong.
Is there a way to send requests inside of while loop
without using async/await
and promises?
Below is my working function with recursion:
function teamsInCity(city, page, result, callback) {
request.get({
url: 'my_service' + '/teams',
qs: { 'city' : city, 'page': page, 'per_page': 1000 },
json: true
}, function(err, response, body) {
if (err) { return callback(err); }
result = result.concat(body.teams);
if (body.more) {
page++;
return teamsInCity(city, page, result, callback);
}
return callback(null, result);
});
}
And here is the route that calls teamsInCity()
router.get('/:city', function(req, res) {
var data = {teams: []};
myService.teamsInCity(req.params.city, 1, [], function(err, teams) {
if (err) {
logger.error('Error while retrieving teams in ' + req.params.city);
}
data.teams = _.sortBy(teams, 'name');
res.send(data);
});
});
Thank you!