1

I'm working on a tool to programmatically grade some testing data and I'm trying to create a MongoDB initialization script to stand up a new instance of the system with testing data. I have two functions, one to delete any existing collections and one to create the new collections, followed up an insert of test data and statement to print it out. My code is as follows:

processDatabases();

async function processDatabases() {

  var MongoClient = require('mongodb').MongoClient;
  var url = "mongodb://localhost:27017/grader";

  client = await MongoClient.connect(url);
  const db = await client.db("grader");

  collections = ['students','tests']


  await deleteCollections(db, collections);
  await createCollections(db, collections);

  var students = db.collection("students");
  students.insertOne({name: "test"});

  db.listCollections().toArray(function(err, collInfos) {
    // collInfos is an array of collection info objects that look like:
    // { name: 'test', options: {} }
    console.log(collInfos);
  });
  //process.exit(0);

};
    
async function deleteCollections(db, collections) {

  // Delete existing collections for database refresh
  console.log("Deleting any existing collections...");
  
  collections.forEach(function(collection_to_drop) {
    db.collection(collection_to_drop).drop(function(err, reply) {

      if (err) {
        console.log("-- could not delete "+ collection_to_drop+": "+reply+"\n")
      }
      else {
        console.log("-- "+collection_to_drop+" collection deleted"+"\n");
      }
    });
  
  });


}

async function createCollections(db, collections){
  console.log("Creating initial collections and test data...");

  collections.forEach(function(collection_to_create) {
    db.createCollection(collection_to_create, function(err, reply){
      if (err) {
        console.log("-- could not create "+ collection_to_create+": "+reply+"\n")
      }
      else {
        console.log("-- "+collection_to_create+" collection create"+"\n");
      }
    });
  });
}

However, when I run the code, the output does not reflect this attempted approach:

C:\Program Files\nodejs\node.exe .\db\init.js
Deleting any existing collections...
db/init.js:34
Creating initial collections and test data...
db/init.js:53
-- students collection deleted

db/init.js:43
-- tests collection deleted

db/init.js:43
(0) []
-- students collection create

db/init.js:61
-- tests collection create

db/init.js:61

What I don't understand is (1) how Node is pushing these functions to the queue of asynchronous functions to run such that the listCollections call is being run before the collection creation functions resolve and (2) why awaiting on deleteCollections doesn't seem to actually wait for the result to come back. I don't do much Node programming, so if someone with more insight into why things are running in this order could help, I'd appreciate it.

  • You marked your functions with `async` but you are not returning a Promise. – Maria Ines Parnisari Apr 03 '22 at 19:36
  • From this: https://nodejs.dev/learn/modern-asynchronous-javascript-with-async-and-await "Prepending the async keyword to any function means that the function will return a promise. Even if it's not doing so explicitly, it will internally make it return a promise." – user8162075 Apr 03 '22 at 22:03
  • Right but when does the promise resolve? E.g. `db.createCollection` has a callback function, but i don't think the code is waiting for it to run. – Maria Ines Parnisari Apr 04 '22 at 02:36
  • This is part of what's not clear to me. It seems like by creating the function as async, it should be resolved in the body of the main function, which is clearly not what's going on. If the call to createCollection is not waiting, how would wrapping it in a promise force it to wait? – user8162075 Apr 04 '22 at 12:02
  • See https://stackoverflow.com/questions/59415498/async-mixed-with-standard-callback – Maria Ines Parnisari Apr 04 '22 at 17:28

0 Answers0