1

The index.js file:

var express = require('express');
var router = express.Router();

function validCheck (exp,name) {
    return exp.test(name);
}
/* GET home page. */
router.get('/', function(req, res, next) {
  res.render('index');
});

var user=db.collection('user'); //gives reference error,db is not defined

router.post('/',function(req,res,next){
    username=req.body.username;
    password=req.body.password;
    //var user=db.collection('user'); //works fine
    user.findOne({'username':username,'password':password},function(err,docs){
        //do something
    });
});

module.exports = router;

When using var user=db.collection('user') outside router.post, it gives the error but when the same is used inside router.post, it works fine.

what might be the concept I am missing here?

Edit: part of App.js file involving mongodb

var mongodb= require('mongodb');
var MongoClient= mongodb.MongoClient;
var URL = 'mongodb://127.0.0.1:27017/mainDB';

MongoClient.connect(URL,function(err,database){
  if(!err){
    db=database;
  }
  else{
    //do something
  }
});
R-R
  • 317
  • 1
  • 6
  • 18

4 Answers4

1

Remember MongoClient.connect() is async. The database connection might not be ready at the time you do var user=db.collection('user');. The database connection has been made one the callback is done, no earlier than that.

When the first request is done, the database connection just happens to be established. The longer you wait the more likely it is that is works, but still it's the wrong approach.

Also working with global variables is bad practice and leads to confusion and other problems.

In short the code should look like

// module database.js
var mongodb= require('mongodb');
var MongoClient= mongodb.MongoClient;
var URL = 'mongodb://127.0.0.1:27017/mainDB';

var db;
var error;
var waiting = []; // Callbacks waiting for the connection to be made

MongoClient.connect(URL,function(err,database){
  error = err;
  db = database;

  waiting.forEach(function(callback) {
    callback(err, database);
  });
});

module.exports = function(callback) {
  if (db || error) {
    callback(error, db);
  } else {
    waiting.push(callback);
  }
}
}

Than use it like

var db = require('database.js');

router.post('/',function(req,res,next){
  username=req.body.username;
  password=req.body.password;

  db.conn(function(err, database) {
    if (err) {
      res.sendStatus(500);
      console.log(err);
      return;
    }

    database.collection('users').findOne({'username':username, 'password':password}, function(err, docs){
      //do something
    });
  });
});

Note that the connection is made on the first require, so if you add require('database.js'); in App.js. You don't loose the on the first request.

Alternatively you can use promises, which takes care of the waiting logic for you.

Community
  • 1
  • 1
Arnold Daniels
  • 16,516
  • 4
  • 53
  • 82
0

What you are missing is the timing of execution.

The var user line outside router.post is executed immediately when index.js is processed by node.js.

The var user line inside router.post is only executed when a client requests the / page of your app.

The db variable is only assigned after the connection to your MongoDB has been made successfully. This is too late for the first var user line, but in time for the first HTTP request to /.

Joost Vunderink
  • 1,178
  • 6
  • 14
0

MongoClient.connect's callback function is called asynchronously only after it is connected to the database. At the time only you are defining db as a global variable.

Assuming you require index.js file in app.js. The line var user=db.collection('user'); outside router.post is executed synchronously. By the time this line is executed db would have not be defined.

The line var user=db.collection('user'); inside router.post is executed asynchronously. So, when that code is executed db is already defined.

To your question:

what might be the concept I am missing here?

I suggest you to learn about asynchronous javascript execution https://stackoverflow.com/a/7104633/3492210

Community
  • 1
  • 1
Anand S
  • 1,068
  • 9
  • 22
0
var mongo = require('mongodb');
var url = "mongodb://localhost:27017/qanda";
mongo.MongoClient.connect(url, function(err, db) {
    if (err) throw err;
    console.log("Database created!");
    db.close();
});
Mohit Sharma
  • 529
  • 1
  • 6
  • 17
  • While this code may answer the question, providing additional context regarding how and/or why it solves the problem would improve the answer's long-term value. You can find more information on how to write good answers in the help center: https://stackoverflow.com/help/how-to-answer . Good luck – nima Oct 13 '21 at 14:56