I'm working on a like/dislike system on an API that works with mongoDB and nodejs and the user is supposed to be able to perform these actions:
- Like the sauce once ( like = 1) and add the user id in a "usersLiked" array
- Cancel his like ( like = 0) and remove the user id from the "usersLiked" array
- Dislike the sauce once (like = -1) and add the user id in an array "usersDisliked"
- Cancel his dislike (like = 0) and supposedly removed the user id from the "usersDisliked" array
The logic of the system like / dislike
I managed to make the user like the sauce, cancel his like and dislike the sauce.
But I am completely blocked on the dislike cancellation because when I try to use again the updateOne method in the condition where we have to cancel the like / dislike I have this error:
Cannot set headers after they are sent to the client
How could Improve the code ?
I'm learning little by little to use the backend commands and here I'm facing a wall.
CodePudding user response:
The error you are getting:
Cannot set headers after they are sent to the client
, is because you are trying to send two HTTP responses for the same request, in this block:
if(likeStatus === 0) {
Sauces.updateOne({_id: req.params.id}, {$inc:{likes:-1}, $pull: {usersLiked:userIdentifiant}})
.then(() => res.status(201).json({message: "Like has been canceled"}))
.catch(error => res.status(400).json(error))
Sauces.updateOne({_id: req.params.id}, {$inc:{dislikes: 1}, $pull: {usersDisliked:userIdentifiant}})
.then(() => res.status(201).json({message: "Dislike has been canceled"}))
.catch(error => res.status(400).json(error))
}
You should wait for update operations to complete, and then send a single response. For example, you can chain the promises like this:
if (likeStatus === 0) {
Sauces.updateOne({ _id: req.params.id }, { $inc: { likes: -1 }, $pull: { usersLiked: userIdentifiant } })
.then(() => {
return Sauces.updateOne(
{ _id: req.params.id },
{ $inc: { dislikes: 1 }, $pull: { usersDisliked: userIdentifiant } }
);
})
.then(() => {
res.status(201).json({ message: ['Like has been canceled', 'Dislike has been canceled'] });
})
.catch((error) => res.status(400).json(error));
}
or even better run them in parallel using Promise.all()