Node.js Async/Await module export

27,942

You have to export synchronously, so its impossible to export client and db directly. However you could export a Promise that resolves to client and db:

module.exports = (async function() {
 const client = await MongoClient.connect(url, {
   useNewUrlParser: true
 });

  const db = client.db(mongo_db);
  return { client, db };
})();

So then you can import it as:

const {client, db} = await require("yourmodule");

(that has to be in an async function itself)

PS: console.error(err) is not a proper error handler, if you cant handle the error just crash

Share:
27,942
Admin
Author by

Admin

Updated on May 03, 2020

Comments

  • Admin
    Admin about 4 years

    I'm kinda new to module creation and was wondering about module.exports and waiting for async functions (like a mongo connect function for example) to complete and exporting the result. The variables get properly defined using async/await in the module, but when trying to log them by requiring the module, they show up as undefined. If someone could point me in the right direction, that'd be great. Here's the code I've got so far:

    // module.js
    
    const MongoClient = require('mongodb').MongoClient
    const mongo_host = '127.0.0.1'
    const mongo_db = 'test'
    const mongo_port = '27017';
    
    (async module => {
    
      var client, db
      var url = `mongodb://${mongo_host}:${mongo_port}/${mongo_db}`
    
      try {
        // Use connect method to connect to the Server
        client = await MongoClient.connect(url, {
          useNewUrlParser: true
        })
    
        db = client.db(mongo_db)
      } catch (err) {
        console.error(err)
      } finally {
        // Exporting mongo just to test things
        console.log(client) // Just to test things I tried logging the client here and it works. It doesn't show 'undefined' like test.js does when trying to console.log it from there
        module.exports = {
          client,
          db
        }
      }
    })(module)
    

    And here's the js that requires the module

    // test.js
    
    const {client} = require('./module')
    
    console.log(client) // Logs 'undefined'
    

    I'm fairly familiar with js and am still actively learning and looking into things like async/await and like features, but yeah... I can't really figure that one out

  • Admin
    Admin almost 6 years
    Ahh I see.. In the end I'll be exporting something that requires a mongo connection, not exporting the connection itself. That does make sense though, thank you :)
  • Jonas Wilms
    Jonas Wilms almost 6 years
    @brocococonut glad to help :)
  • Elad
    Elad over 4 years
    Because you return a function, that approach will open a new connection for each require. isn't it?
  • Jonas Wilms
    Jonas Wilms over 4 years
    @elad no, i return the return value of a function
  • Elad
    Elad over 4 years
    Thanks. So ill need to require this in every function i want to query the DB? feel very 'boilerplatey'
  • Jonas Wilms
    Jonas Wilms over 4 years
    @elad in every file (/module)
  • Jonas Wilms
    Jonas Wilms about 4 years
    This will create multiple clients ...not sure if that is needed. Also the API endpoint will respond with an error if you call it before the db client loaded.
  • Dev AKS
    Dev AKS over 3 years
    How we can achieve the same for es6 imports (import abc from 'sample-module')?
  • Jonas Wilms
    Jonas Wilms over 3 years
    @DevAKS const abc = await import("./sample-module");