I'm making a Node.js Blog API with Mongoose. I'm currently implementing a comments system in which you can up/downvote comments. However If a user hits the like/dislike route twice at a time it doesn't work like planned.
If a user spams the like button there is eg. this check: If a vote exists & liked, remove like and decrease liked count on comment. But if two requests at the same time are incomming it decreases the liked count twice.
Upvote Code:
exports.upvoteComment = async (req, res, next) => {
const { id } = req.params
const comment = await Comment.findById(id)
if (!comment) {
return next(new AppError("Comment not found", 404))
}
const vote = await Vote.findOneAndUpdate({
type: 'comment',
refId: comment.id,
authorId: req.user.id
}, {
type: 'comment',
refId: comment.id,
upvoted: true,
authorId: req.user.id
}, { upsert: true })
if (!vote || !vote.upvoted) {
comment.upvotes = comment.upvotes 1;
}
if (vote && vote.upvoted) {
comment.upvotes = comment.upvotes - 1;
await comment.save()
await vote.remove()
return res.status(200).json({
ok: true,
voted: false,
upvoted: false,
upvotes: comment.upvotes,
downvotes: comment.downvotes
})
}
if (vote && !vote.upvoted) {
comment.downvotes = comment.downvotes - 1;
}
await comment.save()
return res.status(200).json({
ok: true,
voted: true,
upvoted: true,
upvotes: comment.upvotes,
downvotes: comment.downvotes
})
}
Vote Model:
type: {
type: String,
required: true,
enum: ["blog", "comment"]
},
upvoted: {
type: Boolean,
required: true,
},
refId: {
type: mongoose.Schema.Types.ObjectId,
required: true,
index: true
},
authorId: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true
}
How could I fix this problem?
CodePudding user response:
As I almost gave up I wanted to know how Youtube handles likes. So I looked at the network tab, and saw If I unvote the video, a request to /removelike was made. So I implemented a /unvote route and It worked!