Startec
Startec

Reputation: 13206

Mongoose and Express not reflecting changes to Schema until another change is made?

On a post request to express I make the following update to an array in my User schema:

  User.findOne({username: username}, function (err, user) {
    if (err) {
      throw err;
    }
    if (!user) {
      res.status(401).send('No user with that username');
    }
    if (typeof items === 'number') {
      user.update({$push: {cart: items}}, {}, function (err) {
        if (err) {
          console.log('There was an error adding the item to the cart');
          throw err
        } else {
          console.log('update', user);
          res.send(user);
        }
      });
    }
  }

When I log the user in express, or in my application, what happens is that the change I make (in this case the addition to the cart) does not show until the next change is made. It is as if the user when logged and sent, is not updated. I know that when checking my database the change is made (item added) but the user being sent in the response is still the original user (from the original response) (i.e. before the change). How to I send the updated user, that I would think would be returned from user.update?

Upvotes: 0

Views: 572

Answers (1)

Yuri Zarubin
Yuri Zarubin

Reputation: 11677

To do what you're trying to do, would involve using the save() method rather than update(), which involves a bit different implementation. This is because calling update() on the model does not modify the instance of the model, it just executes an update statement on the model's collection. Instead, you should use the findOneAndUpdate method:

if (typeof items === 'number') {
  User.findOneAndUpdate({username: username}, {$push: {cart: items}}, function(err, user){
    // this callback contains the the updated user object

    if (err) {
      console.log('There was an error adding the item to the cart');
      throw err
    }
    if (!user) {
      res.status(401).send('No user with that username');
    } else {
      console.log('update', user);
      res.send(user);
    }
  })
}

Behind the scenes it does the exact same thing you're doing, executing find() and then update(), except that it also returns the updated object.

Upvotes: 1

Related Questions