0

I have my schema designed like this

const templateSchema = new Schema({
  Main: {
    text: String,
    textKey: String,
    index: String,
    part: String,
    overallStatus: String,
    subjects: [
      {
        id: String,
        text: String,
        textKey: String,
        index: String,
        type: String,
        comment: String,
        image: String,
        answer: String,
}

and I have to update subjects text and subject id and I am doing it like this

router.post("/edit", (req, res, next) => {
    Template.findOneAndUpdate({
        id: req.body.id,
        text: req.body.text
    }).then(updatedTemp => {
        console.log(updatedTemp);
        if (updatedTemp) {
            res.status(200).json({
                message: "Template updated.."
            });
        } else {
            res.status(404).json({
                message: "Checklist not found"
            });
        }
    });
});

it returns template updated and status 200 but it doesn't update the new values. How can i access subject ID and subject text in this schema

1 Answers1

0

so, According to the provided schema, you should find inside the array, and update there, you could do something like this:

router.post("/edit", (req, res, next) => {
  Template.update(
    {
      "Main.subjects.id": req.body.oldId,
      "Main.subjects.text": req.body.oldText,
      //you can pass some more conditions here
    },
    {
      $set: {
        "Main.subjects.$.id": req.body.id,
        "Main.subjects.$.text": req.body.text
      }
    }
  )
    .then(updated => {
      if (updated.nModified) {
        res.status(200).json({
          message: "Template updated.."
        });
      } else {
        //not updated i guess
      }
    })
    .catch(error => {
      //on error
    });
});

so payload in body you need to pass :

oldId : <which is currently there>,
oldText:  <which is currently there>,
id: <by which we will replace the id field>
text:<by which we will replace the txt>

NOTE: assuming , id or text will be unique among all the docs.

sample data:

{
    "_id" : ObjectId("5be1728339b7984c8cd0e511"),
    "phases" : [ 
        {
            "phase" : "insp-of-install",
            "text" : "Inspection of installations",
            "textKey" : "",
            "index" : "1.0",
            "subjects" : [...]
        },...]
}

we can update text here like this [in the top most level]:

Template.update({
"_id":"5be1728339b7984c8cd0e511",
"phases.phase":"insp-of-install",
"phases.text":"Inspection of installations"
},{
    "$set":{
        "phases.$.text":"Some new text you want to set"
    }
}).exec(...)

but, incase you want to do deep level nested update, you can have a look at this answer : here by @nem035

Saikat Chakrabortty
  • 2,520
  • 4
  • 22
  • 39
  • { n: 0, nModified: 0, ok: 1 } –  Jan 22 '19 at 08:46
  • can you show me the out put of `Template.find({ "Main.subjects.id": req.body.oldId, "Main.subjects.text": req.body.oldText, }).select({"Main.subjects.$":1}).exec()` ? – Saikat Chakrabortty Jan 22 '19 at 08:49
  • on console its : `{ n: 0, nModified: 0, ok: 1 }` and on my client side which is Angular 4 : **not found please try again** –  Jan 22 '19 at 08:50
  • its backend code, can you try the query i have given in the above comment and give the output? will be easy to help then, and it has nothing to do with angular. – Saikat Chakrabortty Jan 22 '19 at 08:51
  • thats not working either no output because now I cannot click the button –  Jan 22 '19 at 08:55
  • can you try with postman or something may be? triggering the api, with the required payload and headers? because, the above query i gace in comment, this finds and locates the doc, which needs to be updated, if that coming properly, then we can update the update query in the answer accordingly. – Saikat Chakrabortty Jan 22 '19 at 08:59
  • by the way what do you mean by oldID and oldText?. I can post my database maybe you can check then? –  Jan 22 '19 at 09:02
  • lets not post the databse credentials or something here, and `oldID` & `oldText ` means , this are the values which are currently in the place of `id` and `text` in database, and you want to change it to the new `id` and `text` you are passing in payload, i.e `req.body` – Saikat Chakrabortty Jan 22 '19 at 09:04
  • by using `oldId` and `oldText` we are locating the particular doc, which we need to update with the new values, you passing as `id` and `text` – Saikat Chakrabortty Jan 22 '19 at 09:04
  • the collection data you gave is a lot different than the questation you have posted. and i'm not sure, in here, which text or id you want to update, the first level or 2nd or 3rd level ? – Saikat Chakrabortty Jan 22 '19 at 09:11
  • all the level basically. but now we can go with level 1 let's say –  Jan 22 '19 at 09:14