relidon
relidon

Reputation: 2292

How to update with mongoose

I have this record

{
    "_id" : ObjectId("5dfdff479ad032cbbc673507"),
    "selection" : [ 
        {
            "highlights" : "test",
            "comment" : "CHANGE THIS",
            "el" : "body:nth-child(2)>div:nth-child(2)#root>div.App>p:nth-child(1)"
        }, 
        {
            "highlights" : "Barrett’s lyrical prose opens with a clever and tender solution",
            "comment" : "",
            "el" : "body:nth-child(2)>div:nth-child(2)#root>div.App>p:nth-child(2)"
        }
    ],
    "category" : [],
    "status" : "",
    "url" : "http://localhost:3000/theone",
    "title" : "React App test",
    "__v" : 4
}

And I want to update the comment. I have tried to use update and findOneAndUpdate and nothing is working. Here is my attempt

WebHighlight.findOneAndUpdate(
  {
    _id: req.params.highlight,
    "selection.highlights": "test"
  },
  { "selection.$.comment": "yourValue" }
);

That req.params.highlight is the id (I even hardcoded it)

I also tried this

WebHighlight.findById(req.params.highlight, (err, book) => {
  var test = [...book.selection];
  test[0].comment = "somethibf"
  book.save();
  res.json(book);
});

And nothing is working.

This is the model

const webhighlightsModel = new Schema({
  selection: { type: Array, default: "" },
  category: { type: Array, default: [] },
  title: { type: String },
  url: { type: String },
  status: { type: String, default: "" }
});

Upvotes: 0

Views: 44

Answers (2)

SuleymanSah
SuleymanSah

Reputation: 17858

Actually your code seems to work, but findOneAndUpdate returns the old document if you don't give {new: true} option.

I think for this reason, you think the update wasn't successfull, but if you check your collection, you will see the update.

WebHighlight.findOneAndUpdate(
  {
    _id: req.params.highlight,
    "selection.highlights": "test"
  },
  { "selection.$.comment": "yourValue" },
  { new: true }
)
  .then(doc => res.send(doc))
  .catch(err => res.status(500).send(err));

Also I think it would be better if selection had a sub schema like this:

const mongoose = require("mongoose");

const schema = new mongoose.Schema({
  selection: [
    new mongoose.Schema({
      highlights: String,
      comment: String,
      el: String
    })
  ],
  category: { type: Array, default: [] },
  title: { type: String },
  url: { type: String },
  status: { type: String, default: "" }
});

module.exports = mongoose.model("WebHighlight", schema);

So with this every selection would an _id field, and it would be better to update with this _id.

Upvotes: 1

Tunmise Ogunniyi
Tunmise Ogunniyi

Reputation: 2573

You should use the $set operator to update existing values:

WebHighlight.findOneAndUpdate(
  {
    _id: req.params.highlight,
    "selection.highlights": "test"
  },
  { '$set': { "selection.$.comment": "yourValue" } }
);

Upvotes: 0

Related Questions