0

I'm trying to update the subdocument within the array without success. The new data doesn't get saved.

Express:

router.put('/:id/:bookid', (req, res) => {
 library.findOneAndUpdate(
 { "_id": req.params.id, "books._id": req.params.bookid},
 { 
 "$set": {
 "title.$": 'new title'
 }
 }
}); 

LibraryScema:

const LibarySchema = new Library({
 Name: {
 type: String,
 required: false
 }, 
 books: [BookSchema]
});

bookScema:

const BookSchema = new Schema({
 title: {
 type: String,
 required: false
 },
 Chapters: [
 {
 chapterTitle: {
 type: String,
 required: false
 }
 }
 ]
});

I only aim to update the sub-document, not parent- and sub-document at same time.

asked Apr 3, 2018 at 20:34

1 Answer 1

1

I had a similar issue. I believe there is something wrong with the $set when it comes to nested arrays (There was an entire issue thread on GitHub). This is how I solved my issue.

var p = req.params;
var b = req.body;
Account.findById(req.user._id, function (err, acc) {
 if (err) {
 console.log(err);
 } else {
 acc.websites.set(req.params._id, req.body.url); //This solved it for me
 acc.save((err, webs) => {
 if (err) {
 console.log(err);
 } else {
 console.log('all good');
 res.redirect('/websites');
 }
 });
 }
});

I have a user with a nested array.

Try this code

router.put('/:id/:bookid', (req, res) => {
 library.findById(
 req.params.id, (err, obj) => {
 if (err) console.log(err); // Debugging
 obj.books.set(req.params.bookid, {
 "title": 'new title',
 'Chapters': 'your chapters array'
 });
 obj.save((err,obj)=>{
 if(err) console.log(err); // Debugging
 else {
 console.log(obj); // See if the saved object is what expected;
 res.redirect('...') // Do smth here
 }
 })
 })
});

Let me know if it works, and I'll add explanation.

Explanation: You start by finding the right object (library in this case), then you find the correct object in the array called books.

Using .set you set the whole object to the new state. You'll need to take the data that's not changing from a previous instance of the library object.

I believe this way will overwrite and remove any data that's not passed into the .set() method. And then you save() the changed.

answered Apr 3, 2018 at 20:50
Sign up to request clarification or add additional context in comments.

1 Comment

I have a hard time understanding your solution as I'm new to express/mongoose. Any chance you could edit the solution so it work with my case?

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.