Node.js reuse MongoDB reference

mongodb, node.js

Solution

`mydb.js`:

var mongodb= require('mongodb'),
  server = new mongodb.Server('staff.mongohq.com', 10030, {
    auto_reconnect: true
  }),
  db1 = new mongodb.Db('mydb', server);


// callback: (err, db)
function openDatabase(callback) {
  db1.open(function(err, db) {
    if (err)
      return callback(err);

    console.log('Database connected');

    return callback(null, db);
  });
}

// callback: (err, collection)
function authenticate(db, username, password, callback) {
  db.authenticate(username, password, function(err, result) {
    if (err) {
      return callback (err);
    }
    if (result) {
      var collection = new mongodb.Collection(db, 'test');

      // always, ALWAYS return the error object as the first argument of a callback
      return callback(null, collection);
    } else {
      return callback (new Error('authentication failed'));
    }
  });
}

exports.openDatabase = openDatabase;
exports.authenticate = authenticate;

`use.js`:

var mydb = require('./mydb');
// open the database once
mydb.openDatabase(function(err, db) {
  if (err) {
    console.log('ERROR CONNECTING TO DATABASE');
    console.log(err);
    process.exit(1);
  }

  // authenticate once after you opened the database. What's the point of 
  // authenticating on-demand (for each query)?
  mydb.authenticate(db, 'usernsame', 'password', function(err, collection) {
    if (err) {
      console.log('ERROR AUTHENTICATING');
      console.log(err);
      process.exit(1);
    }

    // use the returned collection as many times as you like INSIDE THE CALLBACK
    collection.find({}, {limit: 10})
    .toArray(function(err, docs) {
      console.log('\n------ 1 ------');
      console.log(docs);
    });

    collection.find({}, {limit: 10})
    .toArray(function(err, docs) {
      console.log('\n------ 2 ------');
      console.log(docs);
    });
  });
});

Result:

on success:

 Database connected
 Database user authenticated

------ 1 ------
[ { _id: 4f86889079a120bf04e48550, asd: 'asd' } ]

------ 2 ------
[ { _id: 4f86889079a120bf04e48550, asd: 'asd' } ]

on failure:

Database connected
{ [MongoError: auth fails] name: 'MongoError', errmsg: 'auth fails', ok: 0 }

[Original Answer]:

You're opening the `db` multiple times (once in each `query`). You should open the database just once, and use the `db` object in the callback for later use.

You're using the same variable name multiple times, and that might've caused some confusion.

var mongodb = require('mongodb'),
    server = new mongodb.Server('staff.mongohq.com', 10030, {
        auto_reconnect: true
    }),
    db1 = new mongodb.Db('mydb', server);

function authenticateAndGo(db, handle) {
    db.authenticate('username', 'password', function(err) {
        if (err) {
            console.log(err);
            return;
        }
        console.log('Database user authenticated');

        var collection = new mongodb.Collection(db, 'test');

        handle(collection);
    });
}

function query(handle) {
    db1.open(function(err, db2) {
        if( err ) {
            console.log(err);
            return;
        }
        console.log('Database connected');

        authenticateAndGo(db2, handle);
    });
};
exports.query = query;

I've changed the above code a little (`db1` for the original db, `db2` for the opened db). As you can see, you're opening `db1` multiple times, which is not good. extract the code for opening into another method and use it ONCE and use the `db2` instance for all your queries/updates/removes/...

Problem

I am having trouble understanding node.js. Example, MongoDB access, here's what I've got (mydb.js): ``` var mongodb = require('mongodb'), server = new mongodb.Server('staff.mongohq.com', 10030, { auto_reconnect: true }), db = new mongodb.Db('mydb', server); function authenticateAndGo(db, handle) { db.authenticate('username', 'password', function(err) { if (err) { console.log(err); return; } console.log('Database user authenticated'); var collection = new mongodb.Collection(db, 'test'); handle(collection); }); } function query(handle) { db.open(function(err, db) { if( err ) { console.log(err); return; } console.log('Database connected'); authenticateAndGo(db, handle); }); }; exports.query = query; ``` So, if I want to use it later, I would ``` var mydb = require('./mydb'); mydb.query(function(collection) { collection.find({}, { limit: 10 }).toArray(function(err, docs) { console.log(docs); }); }); ``` But, If I do multiple calls, like so: ``` var mydb = require('./mydb'); mydb.query(function(collection) { collection.find({}, { limit: 10 }).toArray(function(err, docs) { console.log(docs); }); }); mydb.query(function(collection) { collection.find({}, { limit: 10 }).toArray(function(err, docs) { console.log(docs); }); }); ``` I get an exception: ``` Error: db object already connecting, open cannot be called multiple times ``` I think that there is really something fundamental that I do not understand about all this and it is probable that this question is stupid ... Anyway, all help is welcome. Thanks in advance.

Original source