I have a .put route on my Express server that is supposed to allow the user to vote in a poll, incrementing its total votes by 1.
My expectation from using both .findOne and then doc.save() and .findOneAndUpdate is that my document is successfully updated after I increment the poll object’s value by 1 in the label.
Here is my code:
router.put("/vote", async (req, res) => {
// let username = req.body.username;
let pollId = req.body.pollId;
let voteTarget = req.body.voteTarget; // is values like "mango" "pineapple"
const filter = { pollId: pollId };
let pollToUpdate = await Poll.findOne(filter);
let pollOptions = pollToUpdate.options;
let newPollValue;
for (let i = 0; i < pollToUpdate.options.length; i++) {
if (pollOptions[i].label === voteTarget) {
let currentVoteTargetValue = pollOptions[i].votes;
newPollValue = currentVoteTargetValue + 1;
pollOptions[i].votes = newPollValue;
}
}
await pollToUpdate.save();
res.status(200).send(
"successfully updated poll value for " +
voteTarget +
" to value " +
newPollValue
);
As you can see, I have my votes set into the Poll document like this:
options: Array
0: Object
label: "apples"
votes: 0
1: Object
label: "oranges"
votes: 0
2: Object
label: "pineapple"
votes: 0
3: Object
label: "mango"
votes: 0
That is how it looks in the MongoDB database. That is just its field. It is inside of a bigger doc.
This MongoDB documentation page claims I can use doc.save() to accomplish my goal. It doesn’t work, sending Postman requests to increment the poll over and over don’t work.
This other mongodb doc page claims I can use findOneAndUpdate(filter, update) to accomplish my goal. It doesn’t work, the request to +1 to the vote field doesn’t work.
Specifically I am sending this Postmanr equest over and over:
//put route
http://127.0.0.1:8080/api/poll/vote
// body
{
"username": "crono",
"pollId": "tr7b1sli6ufo5no0",
"voteTarget": "pineapple"
}
edit:
Even doing
let newOptions = [...oldOptions];
updateTarget.options = newOptions;
console.log(updateTarget.options, 141);
await updateTarget.save();
does increment the future value of the document as i expect. The console.log statement states that the votes for "pineapple" are 1 and not the 0 it loaded with. I then call await updateTarget.save() which really ought to commit my changes to the database. And yet the next rendition of Postman making a request sets me back at 0. I’m baffled.
>Solution :
Does your schema involves Mixed SchemaType?
Mongoose loses the ability to auto detect and save changes in this situation (https://mongoosejs.com/docs/schematypes.html#mixed).
Try using pollToUpdate.markModified('options'); before calling save.