Baalberith
Baalberith

Reputation: 11

does the nextjs api honor promises?

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

slowclick

response:

0 no found 1 Yes there are 0 no found 1 Yes there are 0 no found

FAST CLIC RESPONSE:

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

Answers (1)

AKX
AKX

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

Related Questions