Senny Kalidien Senny Kalidien - 5 months ago 57
Node.js Question

Node.js + MongoDB global variable and scope

I'm trying to make a single connection to my MongoDB and store the response (database) I get back in a global variable, so I can re-use it in seperate JS file (like the separate files for my routes). I'm following this documentation as example: https://mongodb.github.io/node-mongodb-native/driver-articles/mongoclient.html#mongoclient-connection-pooling.

First try:
var mongodb = require('mongodb'),
MongoClient = mongodb.MongoClient,
MongoURL = "my_mongodb_url:port/database_name",
global.db;

MongoClient.connect(MongoURL, function(err, database) {
db = databse;
console.log(db); // shows stuff
}

console.log(global.db); // shows undefined


After some research I found a possible fix for the problem: create a global variable in Node with a global prefix. But it's still not working...

Second try:

var mongodb = require('mongodb'),
MongoClient = mongodb.MongoClient,
MongoURL = "my_mongodb_url:port/database_name",
global.db;

MongoClient.connect(MongoURL, function(err, database) {
global.db = databse;
console.log(db); // shows stuff
}

console.log(global.db); // shows undefined


The code above is all put in the same file [app.js]. I think it has to do with the scope of MongoClient. But I'm not sure. Is there a way to make this work?

Answer

That's actually just an order-of-execution problem. The MongoClient.connect(...) call is asynchronous. The callback function you're passing is not invoked until the connection is established. The console.log(global.db) that you have at the end, however, is invoked immediately, before the your callback is called.

You actually don't need to explicitly make db global here. Variables defined in the outer scope of a module are in the global scope of the module. Attaching a value to global makes it available across modules, but a better way to expose values between modules is to attach them to exports, so that they can be explicitly imported where needed. If you're only using db within this module, then that's not necessary.