I had a problem when I tried to use forEach
that contained await
inside the loop, so I need to define the async
in front of the forEach
loop and it returned the error.
exports.filterAverageRatingsEachSkillForStudent = async (req, res) => {
let receiver = req.query.receiver;
let result = [];
try {
console.log('receiver id', receiver);
for (let id of receiver) {
console.log('Query String ', id);
const findRating = await FeedbackSchema.find({
receiver: id,
//will add level query later
}).select('ratingL ratingS ratingR ratingW');
console.log('Rating Length', findRating.length);
let totalSpeaking = 0;
let totalWriting = 0;
let totalListening = 0;
let totalReading = 0;
let lengthS = findRating.length;
let lengthR = findRating.length;
let lengthL = findRating.length;
let lengthW = findRating.length;
findRating.forEach((rating) => {
console.log('Speaking star = ', rating.ratingS);
totalSpeaking += rating.ratingS;
});
console.log('Total speaking', totalSpeaking);
console.log('lengthS = ', lengthS);
let highestS = lengthS * 5;
let resultOfSpeakingRate = (totalSpeaking * 5) / highestS;
console.log('Average Speaking Rate ---> ', resultOfSpeakingRate);
findRating.forEach((rating) => {
totalWriting += rating.ratingW;
});
let highestW = lengthW * 5;
let resultOfWritingRate = (totalWriting * 5) / highestW;
findRating.forEach((rating) => {
totalReading += rating.ratingR;
});
let highestR = lengthR * 5;
let resultOfReadingRate = (totalReading * 5) / highestR;
findRating.forEach((rating) => {
totalListening += rating.ratingL;
});
let highestL = lengthL * 5;
let resultOfListeningRate = (totalListening * 5) / highestL;
res.json({
writing: resultOfWritingRate,
speaking: resultOfSpeakingRate,
listening: resultOfListeningRate,
reading: resultOfReadingRate,
});
}
//return res.json(totalRating);
} catch (error) {
console.log(error.message);
}
};
Error, able to solve the async await error but still return me only one response result and after that, it showed cannot sent header
2
Answers
.forEach()
is not async-aware. Use a plainfor/of
loop instead. In fact, pretty much stop using.forEach()
entirely these days as its basically obsolete. With block scope available now withlet
andconst
, there is no reason to use.forEach()
and it’s extra function scope any more. Use a regularfor
loop instead.You can fix this particular code by changing to this:
It also appears that you must not have disclosed all the code for this function because it looks like you’re trying to get
findRating
, but then you never do anything with it.The error you report about cannot set headers after they are sent does not occur in this code since that error is about sending multiple responses to the same incoming request and you don’t send any responses in this code. So, help with that particular error would require disclosing more code or perhaps fixing this function will also fix that (we can’t tell since we can’t see the code that actually causes that error).
You can also make use of Promise.all() if there is no dependency between each iteration. Here is the example –