I'm aware of closures and callbacks in JavaScript but it's obvious I don't get them on an intuitive level.
I have a small app that is scraping data from an API and I can easily console.log
the responses from each request, my problem is I'm trying to gather the data and build an object to save to a file when all requests are complete.
I get that nodejs is a single thread of execution and it doesn't block but I can't figure out where to put the call backs when all the inner requests are finished I can console.log
the built object. You'll see my console.log
lines are in the wrong place and execute before the first response from the inner request.
Breakdown
- Fetch country data
- Loop over countryResponse and use each country id to fetch details
- Add each detail to an array
- Add array to object when all requests are complete.
code
const limit = require("simple-rate-limiter");
let request = limit(require("request")).to(1).per(200);
let options = {
method: 'POST',
url: 'https://myendpoint/details',
headers: {
'cache-control': 'no-cache',
'Content-Type': 'application/json'
},
body: {
"token": "TOKEN",
"method": "countries"
},
json: true
};
global.package = {};
global.services = {};
let countryServices = [];
/*
Country fetch
*/
request(options, function (err, response, countryResponse) {
if (err) {}
package.countries = countryResponse;
countryResponse.forEach(function (entry) {
let innerOptions = {
method: 'POST',
url: 'https://myendpoint/details',
headers: {
'cache-control': 'no-cache',
'Content-Type': 'application/json'
},
body: {
"token": "TOKEN",
"method": "services"
},
json: true
};
//THIS LINE OMG
//let countryServices = [];
innerOptions.body.countryCode = entry.countryCode;
request(innerOptions, function (err, response, innerResponse) {
if (err) {}
countryServices.push(innerResponse);
console.log(" inner response " + entry.countryCode + ' : ' + JSON.stringify(innerResponse, null, ""));
});//END innerResponse
});//END countryResponse.forEach
services = countryServices;
console.log(JSON.stringify(package, null, ""));
console.log(JSON.stringify(countryServices, null, ""));
});//END orderResponse
countryResponse
[
{
"countryCode": 1,
"countryName": "Virgin Islands (U.S.)"
},
{
"countryCode": 7,
"countryName": "Russian Federation"
}
]
innerResponse
[
{
"Type": "1",
"id": 2
},
{
"Type": "2",
"id": 3
}
]