1

I have a program where, upon clicking a button, the "likes" attribute of a randomly fetched MongoDB document is supposed to update. However, it does not. I am able to call the fetched document through the button, not not actually update it:

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))
    });
  });

The button in the ejs file is as simple as:

<form action="/" method="POST">
    <button id="updoot" type="submit">upvote</button>
</form>
VLAZ
  • 26,331
  • 9
  • 49
  • 67
  • 1
    Is `updateOne` function take promise as filter argument ? That's wired! – Nur Oct 22 '21 at 19:41
  • 1
    you might want to update base on `w` field ? then make post "/" handler async, also add `await` keyword before `doc()`, Tips:_ And You don't need to catch error from `updateOne`, express.js will do it for you, just return the promise object. – Nur Oct 22 '21 at 19:48
  • 1
    Btw, [drop the pointless `.then(results => { return results })`](https://stackoverflow.com/q/41089122/1048572) – Bergi Oct 24 '21 at 19:22

2 Answers2

1

Check the status of the promise by console logging (result). If it returns a pending promise, try async-await which will resolve the promise, and then executes 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("/")
  });

I think it should work.

Dharman
  • 30,962
  • 25
  • 85
  • 135
jkalandarov
  • 564
  • 5
  • 15
  • This just doesn't seem to be doing it for me. The console returns: ```{ acknowledged: true, modifiedCount: 0, upsertedId: null, upsertedCount: 0, matchedCount: 0 }``` for the value of updatedData. – Sebastian Przybylski Oct 24 '21 at 21:23
1

Alright, thanks to the contribution of jkalandarov, I was able to solve it just by adding one extra step: requesting the ObjectId of w and using that as a filter instead of the returned promise of 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("/")
  });