Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How do I update this document value in Mongoose? .findOne and then .save() isn't working

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:

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

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.

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading