Tengo un programa en el que, al hacer clic en un botón, se supone que se actualiza el atributo "me gusta" de un documento MongoDB obtenido al azar. Sin embargo, no lo hace. Puedo llamar al documento obtenido a través del botón, no actualizarlo:
MongoClient.connect(DBconnection, { useUnifiedTopology: true }) .then(client => { const db = client.db(database); const collection = db.collection(table); //R has been previously defined as a random number let doc = function(data) { return db.collection(table).find().limit(-1).skip(R - 1).next() .then(results => { return results }) } //This is supposed to update the value of the randomly fetched document app.post("/", (req, res) => { let w = doc() w.then(function(results) { console.log(results) //This correctly returns the random document }) //This line is meant to update document "w", but it does not. db.collection(table).updateOne({ w }, { $set: { likes: "clicked" + R } }) .then(result => { res.redirect("/") }) .catch(error => console.error(error)) }); });El botón en el archivo ejs es tan simple como:
<form action="/" method="POST"> <button id="updoot" type="submit">upvote</button> </form>Verifique el estado de la promesa mediante el registro de la consola (resultado). Si devuelve una promesa pending , intente async-await que resolverá la promesa y luego ejecuta res.redirect .
app.post("/", async (req, res) => { let w = await doc() const updatedData = await db.collection(table).updateOne({ w }, { $set: { likes: "clicked" + R } }) res.redirect("/") });Creo que debería funcionar.
Muy bien, gracias a la contribución de jkalandarov, pude resolverlo simplemente agregando un paso adicional: solicitando el ObjectId de w y usándolo como filtro en lugar de la promesa devuelta de w:
app.post("/", async (req, res) => { let w = await doc() var oid = w._id let updatedData = await db.collection(table).updateOne({"_id":ObjectId(oid)}, { $set: { likes: "clicked" + R } }) res.redirect("/") });