NodeJs API用不完整的对象响应

问题描述 投票:1回答:1

[我正在尝试使用NodeJ来实现API,该NodeJs从数据库集合中读取数据,并再次形成数据从另一个集合中读取各自的数据,并使用新的键值对更新同一对象。

对象已成功更新,但是我在Frontend上收到的API响应未使用第二个集合值更新。

router.get('/exam/:_id' , (req , res) => {
    ExamModel.find({
        userId: req.params._id
    })
        .then(doc => {
            let i=0;
            for(let data of doc){
                i=i+1;
                ResponseModel.find({examId: data._id}).countDocuments()
                   .then(count=>{
                        data.responseCount= count;
                        if(i===doc.length){
                           res.json(doc)
                        }
                    })
                    .catch(err => {
                        res.status(500).json(err)
                    })

            }
        })
        .catch(err => {
            res.status(500).json(err)
        })
})

从ExamModel收到的对象是

[
    {
        _id: "012",
        responseCount: 0,
        data: [array]
    },
    {
        _id: "015",
        responseCount: 0,
        data: [array]
    }
]

在ResponseModel之后,对象成为

[
    {
        _id: "012",
        responseCount: 5,
        data: [array]
    },
    {
        _id: "015",
        responseCount: 2,
        data: [array]
    }
]

但是作为api的响应,我得到的是第一个对象而不是第二个。

而且我也遇到错误

(node:15012) UnhandledPromiseRejectionWarning: Error [ERR_HTTP_HEADERS_SENT]: Cannot set headers after they are sent to the client
    at ServerResponse.setHeader (_http_outgoing.js:470:11)
node.js mongodb api express object
1个回答
0
投票

查询返回的doc对象将处于不可变状态。为了修改该对象,您需要先将其转换为普通的javascript对象。

您可以在for循环之前执行以下操作。

const result = doc.map(d => d.toObject());

现在您可以在循环中使用result对象并将其修改为结果对象。

关于ERR_HTTP_HEADERS_SENT错误。 for循环将完成迭代,并且将在文档计数查询返回promise之前很长时间完成。这将使if(i===doc.length)条件多次成立。

您可以使用如下所示的async / await函数来解决此问题

router.get("/exam/:_id", async (req, res) => {
  try {
    const doc = await ExamModel.find({ userId: req.params._id });
    const result = doc.map((d) => d.toObject());
    for (let data of result) {
      const count = await ResponseModel.countDocuments({ examId: data._id });
      data.responseCount = count;
    }
    res.json(result);
  } catch (err) {
    console.log(err);
    res.status(500).json({ message: "Interval Server Err" });
  }
});
© www.soinside.com 2019 - 2024. All rights reserved.