mcnutty
mcnutty

Reputation: 55

MongoDb forEach asynchronous callback

I am using the Request npm module to extract data from an api and insert it into fields in my Mongo database. Afghanistan, the first country in the database, is the only document that gets populated with data. Every other country gets skipped. The following code console logs the "beginning" and the "end" sequentially, and then logs the country name. I get that this is the result of the asynchronous nature of javascript, but I'm not sure how it affects this code. Shouldn't the console log:

begin
country
end
etc...

Here the code:

MongoClient.connect(url, function(err, db)  {
  db.collection('countries').find().forEach( function(myDoc) {
    console.log('beginning');
    var code = myDoc.country.iso2;
    var options = {
      url: 'https://api.tugroup.com/v1/travelsafe/countries/' + code,
      headers: {
        ['X-Auth-API-Key']: '*******',
        ['Content-Type']: 'application/x-www-form-urlencoded'
      }
    }
    var callback = function(error, response, body)  {
      console.log(myDoc.country.name);
      if (!error && response.statusCode == 200) {
        var info = JSON.parse(body);
        db.collection('countries').updateOne(
            { 'country.name' : myDoc.country.name },
            { $set: {
            'safety.hasAdvisoryWarning' : info.hasAdvisoryWarning,
            'safety.hasRegionalAdvisory' : info.hasRegionalAdvisory,
            'safety.advisories' : info.advisories,
            'safety.advisoryState' : info.advisoryState,
            'safety.advisoryText' : info.advisoryText,
            'safety.lawAndCulture' : info.lawAndCulture,
            'safety.security' : info.safety}
        },
        function(err, result)  {
          console.log(err);
          db.close();
        });
      }
    }
    request(options, callback);
    console.log('end');
  });
});

The console logs:

begin
end
begin 
end
etc...
Algeria
American Samoa
Andorra
etc...

Upvotes: 1

Views: 766

Answers (1)

DAXaholic
DAXaholic

Reputation: 35358

The problem that only the first one is updated is because you close the database connection (db.close) in the callback of updateOne so that after the first update is done your following connection to mongoDB is closed.

If your log output should be like

beginning  
$country  
end  

then you have to move the logging into the callback of your requests or issue your requests sequentially.

Upvotes: 2

Related Questions