skip to Main Content
        try {
            const review = await Review.create({
                user: user.userid,
                place_id: pid,
                stars: stars,
                content: content,
            });

            /* await */ User.findByIdAndUpdate(user.userid, {
                $push: {reviews: review._id}
            });

            res.status(200).json(returnResponse(false, "reviewWritten", "-"));

            return;
        } catch (error) {
            console.error(error);

            res.status(500).json(returnResponse(true, "errorAtReviewWriting", "-"));

            return;
        }

I have written the code as shown above.

I thought that since I don’t need the return value of User.findByIdAndUpdate, I don’t have to use the await keyword and let it run asynchronously. Why does it only work correctly when I use the await keyword?

When I don’t use the await keyword, It’s not updated at all. Literally.

I have verified that the data has not been edited at all by findById() method after saving.

And, error didn’t occur since the returned response code was 200.

2

Answers


  1. Since mongoose will return a promise when there is no callback, you can use .then if you do not want the await

    Review.create({
        user: user.userid,
        place_id: pid,
        stars: stars,
        content: content,
      })
      .then(review => {
        User.findByIdAndUpdate(user.userid, {
          $push: {
            reviews: review._id
          },
        }).exec(); // Returns a fully executable query.
      })
      .then(() => {
        res.status(200).json(returnResponse(false, "reviewWritten", "-"));
      })
      .catch(error => {
        console.error(error);
        res.status(500).json(returnResponse(true, "errorAtReviewWriting", "-"));
      });
    
    Login or Signup to reply.
  2. “Mongoose queries are not promises.

    Queries are thenables, meaning they have a .then() method for async/await as a convenience. However, unlike promises, calling a query’s .then() executes the query…”

    (await uses the .then() of thenables.)

    You can use exec to force execution:

    User.findByIdAndUpdate(user.userid, {
        $push: {reviews: review._id}
    }).exec();
    

    but I wouldn’t recommend it, since if the query fails you’ll get an unhandled rejection, and it’s nice for a response to a request to come only after the effect of the request has actually been (successfully) applied. (For example, with this background .exec(), a follow-up request that came in very quickly could read the pre-update state of the database.*) Just await – straightforward and reliable.

    * This isn’t always a dealbreaker – eventual consistency is a whole thing, and certain Mongo configurations might already exhibit similar behavior – but it’s one more consideration.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search