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
    }
]
 
     
    