skip to Main Content

I have the following code to create a connection to my MongoDB database, and to store it for future use.

const mongodb = require('mongodb');
const MongoClient = mongodb.MongoClient;

// The database will be defined once a connection to between the cluster and mongodb is created
let _database;

const uri = '';
const databaseName = 'db';

const mongoConnect = () => {
    MongoClient.connect(uri)
        .then((client) => {
            _database = client.db(databaseName);
        })
        .catch((err) => {
            console.log(err);
            throw err;
        });
};

const getDb = () => {
    if (_database) {
        return _database;
    }
    throw 'No database found!';
};

module.exports = {
    mongoConnect,
    getDb
}

My problem is that _database is undefined until the connection is made. If my website tries to use the database before _database is defined it will throw an error and crash.

I want to make it so instead of crashing, other portions of my code would just wait until _database is not undefined. Sounds like a await/async solution is needed, but I can’t wrap my head around how to approach implementing something like that here. Any advice would be great!

2

Answers


  1. First approach: To make mongoConnect an async function and await on it before any of the remaining code is executed.

    const mongoConnect = async () => {
        try {
            const client = await MongoClient.connect(uri);
            _database = client.db(databaseName);
        } catch(e) {
            console.log(err);
            throw err;
        }
    };
    

    In the beginning of your code

    await mongoConnect();
    //Remaning code here
    

    Second approach: To make getDb function await till database connection is available

    const mongodb = require('mongodb');
    const MongoClient = mongodb.MongoClient;
    
    const uri = '';
    const databaseName = 'db';
    
    const databasePromise = new Promise((resolve, reject) => {
        MongoClient.connect(uri)
        .then((client) => {
            resolve(client.db(databaseName));
        })
        .catch((err) => {
            reject(err);
        });
    })
    
    const getDb = async () => {
        return await databasePromise;
    };
    
    module.exports = {
        getDb
    }
    

    Sample code for you to run and check the second approach:

    const databasePromise = new Promise((resolve) => {
        console.log("Connecting to db in 5 seconds...")
        setTimeout(() => {
            console.log("Done")
            resolve("done")
        }, 5000)
    })
    
    const getDb = async () => {
        return await databasePromise;
    };
    
    console.time("First_getDb_call")
    getDb().then(res => {
        console.timeEnd("First_getDb_call")
        console.log(res)
        console.time("Second_getDb_call")
        getDb().then(res => {
            console.timeEnd("Second_getDb_call")
            console.log(res)
        })
    })
    Login or Signup to reply.
  2. **Pretty Simple approach ** Just add await before MongoClient.connect function and make function async Now It will wait for the connection to have response then move forward.

    const mongodb = require('mongodb');
    const MongoClient = mongodb.MongoClient;
    
    // The database will be defined once a connection to between the cluster 
    and mongodb is created
    let _database;
    
    const uri = 'mongodb://localhost:27017/mydb';
    const databaseName = 'db';
    
    const mongoConnect = async () => {
    await MongoClient.connect(uri)
        .then((client) => {
            _database = client.db(databaseName);
        })
        .catch((err) => {
            console.log(err);
            throw err;
        });
     };
    
    const getDb = () => { 
      if (_database) {
        return _database;
    }
    throw 'No database found!'; 
    };
    
    
    
    module.exports = {
      mongoConnect,
      getDb
    }
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search