Reputation: 11
I hope you are well, I have a problem, I am learning NEXTJS and working with its api, and it turns out that when I click very fast the promises get bugged. Or something similar, I leave the tests in this short video of 30s and a demonstration of the code, I hope someone can help me, thank you very much.
https://www.youtube.com/embed/K0JTMxpFLQs
------------ CODE ----------
MY REQUEST AXIOS:
axios.post("/api/reaction", data).then((response) => { return response.data }).then(response => {
if (response.react) {
setNew[key].youLike = true
setNew[key].likes = response.likes
setting(setNew => [...setNew])
} else {
setNew[key].youLike = false
setNew[key].likes = response.likes
setting(setNew => [...setNew])
}
})
My backend:
export default async function react(req, res) {
let msg, msg_type, react, likes
let { type, id } = req.body
let myId = mySession(req)
if (myId && type && id) {
react = await youLike(myId, id, type)
console.log(react)
if (react) {
await executeQuery({ query: `DELETE FROM cms_likes WHERE owner_id='${myId}' and type='${type}' and post_id='${id}'` })
await executeQuery({ query: `UPDATE cms_posts SET likes=likes-1 WHERE id='${id}' ` })
react = false
} else {
await executeQuery({ query: `INSERT INTO cms_likes (owner_id,type,post_id,time) VALUES ('${myId}','${type}','${id}','${timeNow("s")}') ` })
await executeQuery({ query: `UPDATE cms_posts SET likes=likes+1 WHERE id='${id}' ` })
react = true
}
likes = await executeQuery({ query: `SELECT likes FROM cms_posts WHERE id='${id}'` })
} else {
msg_type = "error"
msg = "!Opps error al enviar tu peticion"
}
res.send({ msg, msg_type, react, likes: likes[0]?.likes })
}
By clicking the button many times, the like button doesn't do the promise to check if it exists or not very well, and doubles the likes.
EXISTS SLOW CLIC
response:
0 no found 1 Yes there are 0 no found 1 Yes there are 0 no found
FAST CLIC RESPONSE:
2 DUPLICATE 2 DUPLICATE 0 no found 1 Yes there are 0 no found 1 Yes there are 0 no found 3 duplicate
Understand how promises work well, in order to find a solution to this problem, and my post will help people who may have the same error.
My connection SQL and FUNCTION EXECUTEQUERY
const db = mysql({
config: {
host: "localhost",
database: "baalbcms",
user: "root",
password: ""
}
})
export default async function executeQuery({ query, values }) {
try {
const results = await db.query(query, values)
await db.end()
return results
} catch (err) {
return err;
}
}
Upvotes: 1
Views: 458
Reputation: 169042
To make your SQL more robust, you should always count the actual number of likes based on the likes table; as it is, it's possible for those to get out of sync.
I also took the liberty of fixing the SQL injection vulnerabilities in your code by using values
.
This would be better still if you ran the queries in a single transaction, but that can't be easily done with your current db
that you end
after every query (which you shouldn't do).
if (react) {
await executeQuery({
query: "DELETE FROM cms_likes WHERE owner_id=? and type=? and post_id=?",
values: [myId, type, id],
});
} else {
await executeQuery({
query: "INSERT INTO cms_likes (owner_id,type,post_id,time) VALUES (?, ?, ?, ?)",
values: [myId, type, id, timeNow("s")],
});
}
await executeQuery({
query: "UPDATE cms_posts SET likes=(SELECT COUNT(*) FROM cms_likes WHERE type=? and post_id=?) WHERE id=?",
values: [type, id, id],
});
likes = await executeQuery({ query: `SELECT likes FROM cms_posts WHERE id=?`, values: [id] });
Upvotes: 1