将Mongo DB Object DB传递给Express Middleware

时间:2017-01-22 17:39:56

标签: javascript node.js mongodb express

我在尝试访问MongoDB客户端模块连接到MongoDB数据库时创建的“DB”数据库对象时遇到问题。

目前我收到一条错误,指出在data.js中,未定义“db”。我理解为什么这样 - 数据库对象没有被“传递”到路由器然后再传递到控制器。

这样做的最佳方式是什么?

我试图将“db”对象传递给路由器(dataRoutes.js),但我无法想象如何使控制器(data.js)可以访问它。有人可以帮忙吗?

请注意我没有包括其他路线和控制器,但他们只需通过POST方法将表格提交至/ data / submit。下面的控制器用于将此表单数据写入MongoDB数据库。

以下是相关代码:

app.js

var express = require('express');
var path = require('path')
var MongoClient = require('mongodb').MongoClient;
var bodyParser = require('body-parser');
var app = express();

var routes = require('./routes/index');
var dataRoutes = require('./routes/dataRoutes');

app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, 'public')));

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'pug');


MongoClient.connect("mongodb://localhost:27017/m101", function(err, db) {

    if(err) throw err;

    console.log("Successfully connected to MongoDB.");

    app.use('/', routes); // Use normal routes for wesbite
    app.use('/data', dataRoutes); 


    app.get('/favicon.ico', function(req, res) {
      res.send(204);
    });

    app.use(function(req, res, next) {
        var err = new Error('Oops Page/Resource Not Found!');
        err.status = 404;
        next(err); //Proceed to next middleware
    });

    if (app.get('env') === 'development') {
      app.use(function(err, req, res, next) {
// update the error responce, either with the error status
// or if that is falsey use error code 500
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: err
        });
      });
    }

    app.use(function(err, req, res, next) {
        console.log('Error');
        res.status(err.status || 500);
        res.render('error', {
            message: err.message,
            error: {}
        });

    });

    var server = app.listen(3000, function() {
        var port = server.address().port;
        console.log("Express server listening on port %s.", port);
    });

});

dataRoutes.js

    // router

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

    // controller references
    var ctrlsData = require('../controllers/data');

    router.post('/submit', ctrlsData.submit);


    module.exports = router;

data.js

var MongoClient = require('mongodb').MongoClient;

var sendJsonResponse = function(res, status, content) {
  res.status(status);
  res.json(content);
};

module.exports.submit = function(req, res) {
  var title = req.body.title;
  var year = req.body.year;
  var imdb = req.body.imdb;

  /*
  console.log('submitted');
  console.log(req.body);
  sendJsonResponse(res, 201, {title,year,imdb});
  */

  var title = req.body.title;
  var year = req.body.year;
  var imdb = req.body.imdb;



  if ((title == '') || (year == '') || (imdb == '')) {
    sendJsonResponse(res, 404, {
      "message": "Title, Year and IMDB Reference are all required."
    });
  } else {
      db.collection('movies').insertOne(
          { 'title': title, 'year': year, 'imdb': imdb },
          function (err, r) {
            if (err) {
              sendJsonResponse(res, 400, err);
            } else {
              sendJsonResponse(res, 201, "Document inserted with _id: " + r.insertedId + {title,year,imdb});
            }
          }
        );

  }

};

3 个答案:

答案 0 :(得分:9)

db中创建一个引用mongodb的app.js变量:

MongoClient.connect("mongodb://localhost:27017/m101", function(err, db) {

    app.db = db;

    //.....
});

data.js中,从db访问req.app

module.exports.submit = function(req, res) {

    req.app.db.collection('movies').insertOne({ 'title': title, 'year': year, 'imdb': imdb },
        function(err, r) {}
    )
};

答案 1 :(得分:2)

接受的答案不太正确。您不应将自定义对象附加到app对象。这就是app.locals的目的。另外,使用打字稿时,接受的答案将失败。

app.locals.db = db;

router.get('/foo', (req) => {
    req.app.locals.db.insert('bar');
});

当然,它会更长一些,但是您可以确保将来对ExpressJS的更新永远不会干扰您的对象。

答案 2 :(得分:0)

我知道@Bertrand的答案是实用的,但通常不建议这样做。原因是,从软件的角度来看,您应该在软件中实现更好的分离。

$sql = "INSERT INTO Game_table (Email,Card_no,Table_no,Token_key,Bet_amount) VALUES ('$Emails', '$Cards', '$Table', '$Token_key', '$Bet_amount');"; //2nd query Notice this ------------------------------------^ $sql .= " UPDATE LaborRegistered SET balance = balance - '$Bet_amount' WHERE Phone_no ='$Emails';"; if ($conn->multi_query($sql) === true) { // ... }

app.js

var express = require('express'); var path = require('path') var MongoClient = require('mongodb').MongoClient; var bodyParser = require('body-parser'); var app = express(); var routes = require('./routes/index'); var dataRoutes = require('./routes/dataRoutes'); var DB = require('./db.js'); app.use(bodyParser.urlencoded({ extended: false })); app.use(express.static(path.join(__dirname, 'public'))); // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'pug'); DB.Init("mongodb://localhost:27017/m101") .then(() => { console.log("Successfully connected to MongoDB."); app.use('/', routes); // Use normal routes for wesbite app.use('/data', dataRoutes); app.get('/favicon.ico', function(req, res) { res.send(204); }); var server = app.listen(3000, function() { var port = server.address().port; console.log("Express server listening on port %s.", port); }); }) .catch((e) => { console.log("Error initializing db"); });

db.js

var _db = null; module.exports = { Init: (url) => { return new Promise((resolve, reject) => { if (!url) reject("You should provide a URL"); MongoClient.connect("mongodb://localhost:27017/m101", function(err, db) { if(err) reject(err); _db = db; resolve(); // Or resolve(db) if you wanna return the db object }); }); }, Submit: (req, res, next) => { // Whatever goes. You have access to _db here, too! } };

data.js

最后,甚至可以改善此答案,因为通常不建议您等待数据库连接,否则,您将失去使用ASync procs的优势。 考虑类似于var DB = require('../db.js'); router.post('/submit', DB.submit); 中的here的事物:

app.js

我了解在上一个示例中,由于它可能尚未连接,因此无法立即查询数据库,但这是一台服务器,通常希望用户等待数据库初始化。但是,如果您想要更多的证明解决方案,请考虑自己在Promise.resolve() .then(() => { // Whatever DB stuff are // DB.Init ? }) .then(() => { // Someone needs routing? }) ... .catch((e) => { console.error("Ther app failed to start"); console.error(e); }); 中实现某些功能以等待连接。或者,您也可以使用类似mongoose的东西。