Reputation: 29
I am trying to create a script that will populate my Mongo database using data returned from a few API calls. Ideally, this would be run manually every once in a while or on a scheduler to update the database with fresh data, so I am trying to do everything inside of the 'MongoClient.conncect' function. I would like to import this data one API call at a time and am trying to avoid the ugliness of chained promises and .then's. I have done some research on using async/await and it seems to me that using the 'await' keyword is effectively unwrapping the returned promise. If that is the case, I can't quite figure out why it is not waiting properly. Here is what I have so far:
const MongoClient = require('mongodb').MongoClient;
const fs = require('fs');
const assert = require('assert');
const ProPublicaAPI = require('./ProPublicaAPI');
var constants = require('../common/constants');
var https = require('https');
const url = 'mongodb://localhost:27017';
dbName = 'government';
MongoClient.connect(url, function(err, client) {
assert.equal(null, err);
console.log('successfully connected to mongoDB server: ' + url);
const db = client.db(dbName);
try{
var senateInsert = waitInsert(db, 'senate');
}
catch(err) {
console.log(err);
}
console.log('closing database connection');
client.close();
})
async function waitInsert(db, collection) {
//I made this function just to call inside the MongoClient.connect() above
return await insertSenateDocuments(db, collection);
}
function insertSenateDocuments(db, chamber) {
return new Promise(function(resolve) {
var collection = db.collection(chamber);
//method that calls API, to be converted into async/await later
senateMembers = ProPublicaAPI.getAllMembersByChamber(chamber);
senateMembers.then(function(promisedMembers) {
console.log("Recieved data from api");
collection.insertMany(promisedMembers, function(err, result) {
if(err) return console.log(err);
console.log(`Imported ${chamber} data`);
resolve(result);
});
})
})
}
And here is the stack trace:
successfully connected to mongoDB server: mongodb://localhost:27017
about to close
Recieved collection Data
{ MongoError: server instance pool was destroyed
at basicWriteValidations (D:\Dev\node\node_modules\mongodb-core\lib\topologies\server.js:636:41)
at Server.insert (D:\Dev\node\node_modules\mongodb-core\lib\topologies\server.js:737:16)
at Server.insert (D:\Dev\node\node_modules\mongodb\lib\topologies\topology_base.js:315:25)
at executeCommands (D:\Dev\node\node_modules\mongodb\lib\bulk\ordered.js:525:23)
at executeOperation (D:\Dev\node\node_modules\mongodb\lib\utils.js:408:22)
at OrderedBulkOperation.execute (D:\Dev\node\node_modules\mongodb\lib\bulk\ordered.js:602:10)
at bulkWrite (D:\Dev\node\node_modules\mongodb\lib\collection.js:627:8)
at executeOperation (D:\Dev\node\node_modules\mongodb\lib\utils.js:408:22)
at Collection.insertMany (D:\Dev\node\node_modules\mongodb\lib\collection.js:512:10)
at D:\Dev\node\dataimporter\mongo.js:39:18
name: 'MongoError',
message: 'server instance pool was destroyed' }
PS D:\Dev\node\dataimporter> node mongo
successfully connected to mongoDB server: mongodb://localhost:27017
closing database connection
Recieved data from api
{ MongoError: server instance pool was destroyed
at basicWriteValidations (D:\Dev\node\node_modules\mongodb-core\lib\topologies\server.js:636:41)
at Server.insert (D:\Dev\node\node_modules\mongodb-core\lib\topologies\server.js:737:16)
at Server.insert (D:\Dev\node\node_modules\mongodb\lib\topologies\topology_base.js:315:25)
at executeCommands (D:\Dev\node\node_modules\mongodb\lib\bulk\ordered.js:525:23)
at executeOperation (D:\Dev\node\node_modules\mongodb\lib\utils.js:408:22)
at OrderedBulkOperation.execute (D:\Dev\node\node_modules\mongodb\lib\bulk\ordered.js:602:10)
at bulkWrite (D:\Dev\node\node_modules\mongodb\lib\collection.js:627:8)
at executeOperation (D:\Dev\node\node_modules\mongodb\lib\utils.js:408:22)
at Collection.insertMany (D:\Dev\node\node_modules\mongodb\lib\collection.js:512:10)
at D:\Dev\node\dataimporter\mongo.js:39:18
name: 'MongoError',
message: 'server instance pool was destroyed' }
As you can see, the client.close() is being called before the inserting of the documents is taking place.
Upvotes: 0
Views: 696
Reputation: 4573
You have to await
for waitInsert
MongoClient.connect(url, async function(err, client) {
assert.equal(null, err);
console.log('successfully connected to mongoDB server: ' + url);
const db = client.db(dbName);
try{
var senateInsert = await waitInsert(db, 'senate');
}
catch(err) {
console.log(err);
}
console.log('closing database connection');
client.close();
})
Upvotes: 3
Reputation: 1
Easier:
bulkWriteItems(array, collection) {
return collection.bulkWrite(array, {ordered: true, w: 1})
}
Call:
async saveData() {
let bulk = [];
for (let i = 0; i < 100; i++) {
let name = `item${i}`
bulk.push({insertOne: {name}});
}
return db.collection(COLLECTION_OBJECTS).then(collection => this.bulkWriteItems(bulk, collection))
}
Upvotes: 0