4
\$\begingroup\$

I want my entire node application to use one single mongodb connection, at least that's what I think is better. I wrote this little script and want some feedback on it. Especially if what I'm doing makes sense.

This is my mongodb.js file

'use strict';    

// Mongodb module.
var MongoClient = require( 'mongodb' ).MongoClient;    

// Database.
var db;    

// Working variable.
var working;    

// Callbacks array.
var arr = [];    

// Exported variable.
module.exports = function( callBack ) {
    if ( db ) {
        callBack( db );
        return;
    }    

    arr.push( callBack );    

    if ( working ) return;    

    working = true;    

    var MongoDB = MongoClient.connect( 'mongodb://127.0.0.1:27017/test', 
        function( err, res ) {
            if( err ) throw err;    

            console.log( "Connected to MongoDB!" );    

            db = res;    

            for ( var i = 0; i < arr.length; i++ ) { 
                arr[i]( res );
            }    

            arr = [];
        }
    );
}

This is a file where I include the mongodb.js

var collection;
new require( 'mongodb.js' )( 
    function( db ) { 
        collection = db.collection( 'test' ); 
    }
);
\$\endgroup\$
2
\$\begingroup\$

If you make your custom callback node style (i.e. function(err, result)), you can simplify this greatly:

'use strict';
var MongoClient = require('mongodb').MongoClient,
    db;


module.exports = function connectToMongo(url, callback) {
    if (db) { callback(null, db); }
    else { 
        MongoClient.connect(url, function(err, conn) {
            db = conn;
            callback(err, conn);
        });
    }
}

And use it:

var connectToMongo = require('./mongodb.js');

/* ... */

connectToMongo('mongodb://127.0.0.1:27017/test', function(err, db) {
    collection = db.collection('test');
});

An even better option would be to use Promises. I use bluebird in my projects, but we'll soon have native Promise support (bluebird will probably still be better).

var mongo = require('mongodb'),
    Promise = require('bluebird');

Promise.promisifyAll(mongo);
Promise.promisifyAll(require('mongodb/lib/mongodb/db').Db.prototype);

var db;

module.exports = function connectToMongo(url) {
    if (!db) {
        db = mongo.connectAsync(url); //This returns a promise!
    }
    return db;
};

Then use it like

var connecttoMongo = requiure('./mongodb.js');
connectToMongo('mongodb://127.0.0.1:27017/test').then(function(conn) {
    //Do stuff here
});
\$\endgroup\$
1
  • \$\begingroup\$ Please, note that first approach can call MongoClient.connect() multiple times because of race conditions. Author's version is better in this case. The second one is fine. \$\endgroup\$ Mar 30 '15 at 14:37

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.