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!
Advertisement
Answer
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) }) })