NodeJs API отвечает неполным объектом - PullRequest
1 голос
/ 29 мая 2020

Я пытаюсь реализовать API, используя NodeJs, который считывает данные из коллекции базы данных и снова формирует, что данные считывают соответствующие данные из другой коллекции и обновляют тот же объект с новыми парами значений ключа.

Объекты обновляются успешно, но ответ API, который я получаю на Frontend, не обновляется значениями второй коллекции.

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)

1 Ответ

3 голосов
/ 29 мая 2020

Объект doc, возвращенный запросом, будет в неизменяемом состоянии. Чтобы изменить объект, вам необходимо сначала преобразовать его в простой объект javascript.

Вы можете выполнить описанную ниже операцию перед for l oop.

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

Теперь вы можете использовать в себе объект result для l oop и внести изменения в объект результата.

Относительно ошибки ERR_HTTP_HEADERS_SENT. for l oop завершит итерацию задолго до того, как запрос count вернет обещание. Это сделает условие 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" });
  }
});
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...