【问题标题】:Mongoose findOne Returns Null Object ValueMongoose findOne 返回空对象值
【发布时间】:2018-08-07 07:19:43
【问题描述】:

我已经成功在 mongodb compass 中保存了一些文档。我试图通过查询一些参数来检索值。

我知道 mongodb findOne 有诸如 query, fields(by default value: all), options and callback 但是操作的结果返回null并抛出类型错误。

这是我的代码:

router.get('/edit-page/:slug',(req,res) => {
  console.log('slug:\t' + req.params.slug);
  Pages.findOne({slug: req.params.slug},(errs, page) => {
    if(errs){
      req.flash('danger', 'page not found');
      console.error(errs);
    } else {
      console.log(page);
      res.render('admin/edit_page',{
        title: page.title,
        slug: slug,
        content: page.content,
        id: page._id
      });
    }
  });
});

我在 mongo compass 中的数据结构的副本:

{   
  "_id":"5a9568fa5ce418423ca8e29f",
  "title":"Home",
  "slug":"home",
  "content":"Home Page for Node CMS Cart",
  "sorting":100,
  "__v":0
}

抛出错误:

GET /admin/routes 200 8.634 ms - 3064
slug:    about-us
null
events.js:183
     throw er; // Unhandled 'error' event
     ^

TypeError: Cannot read property 'title' of null
    at Pages.findOne (E:\nodeCMSApp\routes\admin_routes.js:98:29)
    at model.Query.<anonymous> 
(E:\nodeCMSApp\node_modules\mongoose\lib\model.js:3928:16)
    at E:\nodeCMSApp\node_modules\kareem\index.js:297:21
    at E:\nodeCMSApp\node_modules\kareem\index.js:135:16
    at _combinedTickCallback (internal/process/next_tick.js:131:7)
    at process._tickCallback (internal/process/next_tick.js:180:9)
[nodemon] app crashed - waiting for file changes before starting...

我似乎不明白为什么在我的回调中,我无法获得对 page.title 的引用,因为未指定时默认字段是所有字段。

PS:Pages 是我的模型类。

如果是,我该如何解决这个问题? 谢谢。

【问题讨论】:

  • 你可以添加你正在调用的 URL。
  • 你能告诉添加这些语句是什么打印的 console.log('slug:\t' + req.params.slug); console.log(page);
  • @Pavan,slug 打印正确,因为它来自 req 正文。但是,页面值为空
  • @RahulSharma,这是完整的 URL localhost:4003/admin/routes/edit-page/%20about-us。我不知道为什么要附加 %20,但这似乎不是问题
  • 代码看起来很好,只有你必须处理条件。

标签: node.js mongodb express mongoose mongodb-query


【解决方案1】:

代码没问题,你需要处理条件。

router.get('/edit-page/:slug', (req, res) => {
    console.log('slug:\t' + req.params.slug);
    Pages.findOne({
        slug: req.params.slug
    }, (errs, page) => {
        if (errs) {
            req.flash('danger', 'page not found');
            console.error(errs);
        } else {
            console.log(page);
            if (page) {
                res.render('admin/edit_page', {
                    title: page.title,
                    slug: slug,
                    content: page.content,
                    id: page._id
                });
            } else {
                res.status(400).send('Error message');
            }
        }
    });
});

【讨论】:

  • 你说得对。它打印“错误消息”,但如何解决?
  • 这是解决方案,因为您无法控制用户输入。如果数据库中有可用的 slug 数据,它将起作用。但是您需要处理负面情况,否则服务器代码将中断。除了消息,您还可以重定向到错误页面。
  • Slug 数据在 db 中可用,但为什么代码会中断?
  • 您是否传递了相同的 slug,如果您愿意,也可以忽略大小写。那就试试
【解决方案2】:
  router.get('/edit-page/:slug', (req, res) => {
      Page.findOne({slug : req.params.slug}).then((page) => {
        if(!page) { //if page not exist in db
          return res.status(404).send('Page not found');
        }
        res.render('admin/edit_page', { //page  exist
          title: page.title,
          slug: page.slug,
          content: page.content,
          id: page._id
        });
      }).catch((e) => {//bad request 
        res.status(400).send(e);
      });
    });

使用此代码,它的逻辑是相同的,但我已经使用它肯定对我有用的 Promise 处理了这些条件。希望对你有帮助:)

【讨论】:

    猜你喜欢
    • 2018-04-03
    • 2016-10-08
    • 1970-01-01
    • 2017-08-18
    • 2013-01-17
    • 1970-01-01
    • 2021-09-03
    • 2016-07-14
    • 2018-07-07
    相关资源
    最近更新 更多