Mongoose .save() is not working?

Hi all, I’m using mongoose for my Voting application and I am unable to get .save() to work in this specific case for some reason. My code is below:

app.post('/polls/update/:pollId', (req, res) => {

  User.findOne({polls: {$elemMatch: {id: req.params.pollId}}}, (err, user) => {
    if (!err){
      console.log('found the user the votes are currently', user.polls[0].votes) //displays correct array (not updated yet)
      user.polls[0].votes = req.body.newVoteState //sets the array to the correct state
      user.save((err) => {
        if(err){
          console.log(err);
        } else {
          console.log('you saved'); //i see this in the console too
        }
      });
      console.log('saved votes are now', user.polls[0].votes); //this displays the correctly updated state
    } else {
      console.log(err);
    }
  });
  res.json({status: "OK"});
});

However, when I fire up my mongoshell, all my vote arrays are set to their default state (ie [0,0] for a poll with 2 options).

Can anyone help me out here? I’m a bit stumped.

Thank you everyone

Are you saving polls votes inside the single users? Why is that?

My schema looks like this:

let userSchema = new Schema ({
  email: {type: String, required: true, unique: true},
  password: {type: String, required: true},
  username: {type: String, required: true, unique: true},
  polls: {type: Array, default: []}
});

so for a given user, polls looks like

polls: [
  {id: '2342342wafasdfr2r', title:'fav color', options: ['red', 'blue'] votes:[0,3]},
  {...},
  {...}
]

Not sure if this is the wrong way to do it, but it is what i have right now

I feel like it might have something to do with your query. I’ve tried using $elemMatch before and I never got it to work. I was able to retrieve the object I was looking for, but for some reason I wasn’t able to update it. I believe you might also need to call markModified on the array you are updating. So it would be something like:

user.markModified("polls");
user.save();
4 Likes

@codefu-chivy it seems markModified() fixed this for me! I had not heard of this function before. Thanks for pointing it out! This is definitely not the first time you’ve helped me throughout this project so thank you for your time, I really appreciate it :slight_smile:

1 Like

You’re very welcome! Yeah I’ve had this same problem in the past and I had to scour the internet before I found this function.

1 Like

Thank you! This just worked for my solution as well- it wouldn’t save until I used this function!

Since it is a schema-less type, you can change the value to anything else you like, but Mongoose loses the ability to auto detect and save those changes. To tell Mongoose that the value of a Mixed type has changed, you need to call doc.markModified(path) , passing the path to the Mixed type you just changed.

https://mongoosejs.com/docs/schematypes.html

Thanks a lot I search thi everywhere I found this function one time but I didnt got the idea what exactly it does and where to use. Now I do. Thanks. I made a new account here to type this comment :smiley:

Hello, I was having the same problem as well and it took me days to solve. For me, the problem was that my app was not successfully connecting to the database and you can check this using the code

mongoose.connection.readyState.

The returned value 1 means connected, 0 means not connected and 2 means connecting.
My prefered method of checking if it connects is by using the code

mongoose.connect( connectionURL, {useNewUrlParser: true, useUnifiedTopology: true}, () => console.log( mongoose.connection.readyState ) );

After trying to connect, it will return the connection state in the callback which is pretty neat.

The reason it was not connecting is that my password in the connectionURL had special characters in it such as the @ symbol. Changing my password to not include any special character solved the problem.
Another solution could be encoding the password’s special characters as advised by the MongoDB docs.

Hope this solves your problem, good luck.