Reputation: 307
I am trying to implement API using NodeJs that reads data from database collection and again form that data reads respective data from another collection and updating same object with new key value pairs.
The objects are updating successfully but the API response that I recieve on Frontend is not updated with second collection values.
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)
})
})
The object recieved from ExamModel is
[
{
_id: "012",
responseCount: 0,
data: [array]
},
{
_id: "015",
responseCount: 0,
data: [array]
}
]
after ResponseModel the object become
[
{
_id: "012",
responseCount: 5,
data: [array]
},
{
_id: "015",
responseCount: 2,
data: [array]
}
]
But as a response of api, I am getting the first object not second.
And also I am getting error
(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)
Upvotes: 1
Views: 325
Reputation: 2011
The doc
object returned by the query will be in an immutable state. In order to modify the object, you need to convert it to a plain javascript object first.
You can perform the below operation before the for
loop.
const result = doc.map(d => d.toObject());
Now you can use the result
object in you for loop and make modification the result object.
Regarding the ERR_HTTP_HEADERS_SENT
error. The for
loop will complete the iteration long before the count query returns the promise. This will make the if(i===doc.length)
condition true multiple times.
You can use async/await function as below in order to solve the issue
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" });
}
});
Upvotes: 3