Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/461.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将Mongo DB对象数据库传递给Express中间件_Javascript_Node.js_Mongodb_Express - Fatal编程技术网

Javascript 将Mongo DB对象数据库传递给Express中间件

Javascript 将Mongo DB对象数据库传递给Express中间件,javascript,node.js,mongodb,express,Javascript,Node.js,Mongodb,Express,我在尝试访问MongoDB客户端模块连接到我的MongoDB数据库时创建的“DB”数据库对象时遇到问题 目前,我收到一个错误,指出data.js中没有定义“db”。我理解这是为什么——db对象没有“传递”到路由器,然后再传递到控制器 最好的方法是什么 我曾尝试将“db”对象传递给路由器(dataRoutes.js),但我不知道如何使控制器(data.js)能够访问它。有人能帮忙吗 请注意,我没有包括其他路由和控制器,但它们只是通过POST方法向/data/submit提交表单。下面的控制器用于将

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

目前,我收到一个错误,指出data.js中没有定义“db”。我理解这是为什么——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});
            }
          }
        );

  }

};

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

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

    app.db = db;

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

    req.app.db.collection('movies').insertOne({ 'title': title, 'year': year, 'imdb': imdb },
        function(err, r) {}
    )
};
data.js
中,从
req.app
访问
db

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

    app.db = db;

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

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

我知道@Bertrand的答案是实用的,但通常不推荐使用。原因是,从软件的角度来看,您的软件应该有一个更好的分离

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");
  });
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!
  }
};
var DB = require('../db.js');
router.post('/submit', DB.submit);
db.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");
  });
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!
  }
};
var DB = require('../db.js');
router.post('/submit', DB.submit);
data.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");
  });
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!
  }
};
var DB = require('../db.js');
router.post('/submit', DB.submit);
最后,即使这个答案也可以改进,因为通常不建议您等待DB连接,否则,您将失去使用异步过程的优势。 考虑类似于<代码> 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);
  });

我知道在上一个示例中,您不能立即查询数据库,因为它可能还没有连接,但这是一个服务器,用户通常需要等待您的数据库初始化。但是,如果您想得到更多的证明方案,请考虑在代码< > db中实现一些事情。提交< /COD>等待连接。或者,您也可以使用类似的方法。

公认的答案并不完全正确。您不应该将自定义对象附加到
应用程序
对象。这就是
app.locals
的用途。另外,当使用Typescript时,接受的答案将失败

app.locals.db=db;
路由器.get('/foo',(req)=>{
请求app.locals.db.insert('bar');
});

当然,它会更长,但您可以得到保证,将来对ExpressJS的更新不会干扰您的目标。

谢谢-回答得好!令人惊叹的!这比通过每个路由器层传递变量容易一百万倍。非常感谢。但是这种方法的缺点是什么呢?本教程更好。