Fez Vrasta
Fez Vrasta

Reputation: 14835

Connect synchronously to mongodb

I would like to connect to mongodb first, then run everything else in my application.

To do it I have to write something like:

MongoClient.connect("mongodb://localhost/test", function(err, connection) {
    if (err) { console.error(err); }
    db = connection;

    var app = express();

    // Include API V1
    require("./apiv1.js")(app, db);

    app.listen(3000, function(err) {
        if (err) { console.error(err); } else { console.log("Started on *:3000"); }
    });
});

This makes my app to be completely indented inside the .connect function... Which looks ugly and takes space while I work on my project.

I think the best solution would be have the MongoDB connection synchronous (even because witout the DB connection my app cannot work so why should I do something while it's connecting?) and then run the rest of my code.

How can I do?

Upvotes: 37

Views: 20091

Answers (4)

lee shin
lee shin

Reputation: 894

You can do it with thunky, thunky executes an async function once and caches it, the subsequent calls are returned from the cache.

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

var connect = thunky(function(cb){
 let url = 'mongodb://localhost:27017/test';
 MongoClient.connect(url, function(err, client){
    console.log('connecting')
    cb(err, client);
 })
})

connect( (err, client) => {
  console.log('connection 1')
})

connect( (err, client) => {
  console.log('connection 2')
})

connect( (err, client) => {
  console.log('connection 3')
  console.log('closing')
  client.close();
})

*Note: I am using latest 3.x mongodb driver

Upvotes: 0

Proteo5
Proteo5

Reputation: 63

If you are using Node 6 and up versions, you can do something like this:

const MongoClient = require('mongodb').MongoClient;
const url = 'mongodb://localhost:27017/mydb';
let db = null;
getdb();

//your code

async function getdb() {
     db = await MongoClient.connect(url);
}
  1. Bring the mongodb library.
  2. Declare the url constant .
  3. Declare the variable db as null.
  4. Call the getdb function.
  5. Create the getdb function which has firt the async word
  6. Assign to the db variable the result of the connection with the key word await.

Upvotes: -1

cillierscharl
cillierscharl

Reputation: 7117

Using the async library, you can aleve some of these issues.

For example in my server startup I do the following :

async.series([
    function(callback){
        // Initialize the mongodb connection and callback on completion in init.
        db.init(function(){
            callback();
        });
    },
    function(callback){
        // Listen on requests etc.
        webServer.init(function(){
            callback();    
        });
    },
    function(callback){
        // Set up anything else that I need
        callback();
    }
]);

Upvotes: 3

Leonid Beschastny
Leonid Beschastny

Reputation: 51500

You can't connect to MongoDB synchronously, but you may get rid of this ugly callback from your code.

The best way to do it is to adopt some wrapper around node-mongodb-native driver.

Take a look at the following modules.


mongojs

var mongojs = require('mongojs');
var db = mongojs('localhost/test');
var mycollection = db.collection('mycollection');

mongoskin

var mongo = require('mongoskin');
var db = mongo.db("mongodb://localhost:27017/test", {native_parser:true});

monk

var monk = require('monk');
var db = monk('localhost/test');
var users = db.get('users')

Of course, internally all of them are establishing MongoDB connection asynchronously.

Upvotes: 32

Related Questions