Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Node Express MongoDB Native Driver — Where to open the DB connection?

I want to open and initialise the DB via Node-Mongo-Native-Driver once in the app.js file and then leave it open and do reads in the routes. I put following code in the app.js and wrapping the app.gets in order to made them available when the DB is opened:

var mongoClient = new MongoClient(new Server('localhost', 27017));
mongoClient.open(function(err, mongoClient) {
  var db1 = mongoClient.db("dev-db")
    , products = db1.collection('products');
  app.get('/', routes.index);
  app.get('/users', user.list);
});

When I try now to read the DB in the index.js route I get

ReferenceError: products is not defined

I thought that index.js should be able to access products since it was defined in a outer function due to wrapping the app.gets in the initialisation.

Besides a 2nd question: what's the difference between MongoClient.open and MongoClient.connect

like image 385
user976647 Avatar asked Jan 29 '13 04:01

user976647


People also ask

How use MongoDB native driver?

Connection Guide: connect to a MongoDB instance or replica set. Authentication: configure authentication and log a user in. CRUD Operations: read and write data to MongoDB. Promises and Callbacks: access return values using asynchronous Javascript.

How do you see the mongos connection?

To connect to a MongoDB Server using username and password, you have to use 'username@hostname/dbname'. Where username is the username, password is the password for that user, dbname is the database to which you want to connect to and optionally you can specify a port number at which you want to connect to.


1 Answers

JavaScript uses lexical scoping - meaning, if you did this it would work:

var mongoClient = new MongoClient(new Server('localhost', 27017));
mongoClient.open(function(err, mongoClient) {
  var db1 = mongoClient.db("dev-db")
    , products = db1.collection('products');
  app.get('/', function closedOverIndexRoute(req, res, next) {
    console.log(products); // this will work
  });
  app.get('/users', user.list); // however, user.list will not be able to see `products`
});

A function doesn't become a closure (doesn't retain the values of its enclosing function) unless it's lexically (written) inside of the closure.

However, you probably don't want to write your whole app as one big closure. Instead, you can use exports and require to get access to your products collection. For example, in a file called mongoconnect.js:

var mongoClient = new MongoClient(new Server('localhost', 27017));
var products;

mongoClient.open(function(err, mongoClient) {
  var db1 = mongoClient.db("dev-db");
  products = db1.collection('products');
});

module.exports = {
  getProducts: function() { return products; }
};

Then in your index.js file:

var products = require('mongoconnect').getProducts();

Another option (if you want to keep just app and index) is to use a pair of closures:

index.js:

module.exports = function(products) {
  return function index(req, res, next) {
    console.log(products); // will have closed-over scope now
  };
};

app.js, inside of mongoClient.open(), where products is defined:

var index = require('./index')(products);
like image 148
hunterloftis Avatar answered Sep 21 '22 03:09

hunterloftis