【问题标题】:Blank document and unhandled promise rejection when making an add subdocument request发出添加子文档请求时的空白文档和未处理的承诺拒绝
【发布时间】:2021-02-13 04:23:18
【问题描述】:

我正在处理我的第一个请求,该请求将向 MongoDB 中的文档添加子文档,我正在努力解决它。我的数据库是用户的集合,每个用户都有一系列他们正在学习的单词,以便在我正在构建的应用程序中进行翻译。我目前有两个问题

  1. 当我在邮递员中请求向我的用户的单词数组添加一个新单词时,我添加了一个具有 ID 的新对象,但没有我在单词子模型中拥有的其他属性值对,并且在请求中(希腊语、英语、成功、时间戳)。

  2. 我的命令提示符给了我以下错误

(node:8320) UnhandledPromiseRejectionWarning: 未处理的承诺 拒绝。此错误源于在异步内部抛出 没有 catch 块的函数,或者通过拒绝一个承诺 不使用 .catch() 处理。 (拒绝 ID:3)(节点:8320) UnhandledPromiseRejectionWarning: ValidationError: 用户验证 失败:words.0.greek:路径greek 是必需的。,words.0.english: 路径english 是必需的。,words.0.success:路径success 是 必填,words.0.timeStamp:路径timeStamp是必填项。

第二个错误令人困惑,因为在我看来应该是 word.greek 和 words.english 从每个 word 对象中获取值。但是,它会在对象及其属性/值对之间添加一个 0。

我的子文档的猫鼬模型如下

const wordSchema = new Schema({
  greek: {
    type: String,
    required: true,
    trim: true,
    minlength: 1,
    index: { unique: true, sparse: true },
  },
  english: {
    type: String,
    required: true,
    minlength: 1
  },
  success: {
    type: Number,
    required: true
  },
  timeStamp: {
    type: Date,
    required: true
  },
});

这是我将单词添加到用户的单词数组中的请求。

router.post("/update/:id",(req, res) =>{
    console.log(req.body.greek)
    var greek = req.body.greek;
    var english = req.body.english;
    var success = req.body.success;
    var timeStamp = req.body.timeStamp
    var newWord = {
        greek: greek,
        english: english,
        success: success,
        timeStamp: timeStamp
    }
    User.findById(req.params.id)
    .then((user) => {
      user.words.push(newWord);
      user.save()
      res.status(200).json(user)
      .catch((err) => {res.status(400).json(err)})
    })
    .catch((err) => {res.status(400).json("Error: "+err)})
});

任何帮助将不胜感激!我已经在谷歌上搜索了一些关于向文档添加子文档的方法,但我仍然没有找到解决方案。

【问题讨论】:

    标签: node.js mongodb express mongoose


    【解决方案1】:

    我看到的一件事是user.save() 将返回一个您不处理的承诺,因此不会保存文档。或许可以考虑:

    User.findById(req.params.id)
    .then(async (user) => {
        user.words.push(newWord);
        await user.save()
        res.status(200).json(user)
        .catch((err) => {res.status(400).json(err)})
    })
    .catch((err) => {res.status(400).json("Error: "+err)})
    

    【讨论】:

      【解决方案2】:

      您可以在一个 DB 调用中直接更新文档,而不是获取然后更新文档。

      router.post("/update/:id",(req, res) =>{
          console.log(req.body.greek)
          var greek = req.body.greek;
          var english = req.body.english;
          var success = req.body.success;
          var timeStamp = req.body.timeStamp
          var newWord = {
              greek: greek,
              english: english,
              success: success,
              timeStamp: timeStamp
          }
          User.findOneAndUpdate({ _id: req.params.id }, {
                  $push: {
                      words: newWord
                  }
              })
          .then((user) => {
            if(!user){
                      return res.status(404).json({ 
                          message: 'Not User matches given ID'
                      });
                  }
      
                  res.status(200).json(user);
          })
          .catch((err) => {res.status(400).json("Error: "+err)})
      });
      

      【讨论】:

      • 我实现了该修复,但不幸的是,我仍然得到只有一个 id 用于我的新词的对象。
      • 你的意思是只有 objectId 出现在新创建的子文档中?
      • 是的,但我想我离罪魁祸首越来越近了。我在 findOneAndUpdate 方法之前添加了一个 console.log(newWord),它说希腊语、英语、成功和时间戳是未定义的。
      • 看起来 req.body 是空白的。是时候再谷歌一下了!
      • 你知道吗,在某个地方,我不小心将邮递员请求从 JSON 转换为文本,这破坏了一切。现在您的解决方案完美运行(但我发现了一个新错误#codingLife)谢谢!
      猜你喜欢
      • 2017-08-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-31
      • 2023-03-17
      相关资源
      最近更新 更多