简体   繁体   中英

Updating embedded document from request body with mongoose

I'm going insane trying to figure out an efficient way to accomplish such a simple task with Mongoose.

I have a Customer and Dog Schema, the Dogs are embedded in the Customer document. I then PUT an updated Dog object to the server and attempt to update the matching embedded object with the following code.

Customer.findById(req.params.cust_id).exec(function(err, customer) {
            if (err) return next(err);
            var dog = customer.dogs.id(req.params.dog_id)
            dog.update(req.body, function(err, dog) {
                if (err) return next(err);
                res.json({
                    message: 'Dog updated.'
                });
            });
        });

This gives me the error "The #update method is not available on EmbeddedDocuments". Ok, fair enough. So since I can't call update to merge the request body with the document to be updated, what is an alternative to efficiently update the entire document (basically a merge) using the request body (the updated dog).

I do not want to type out each property to update.

UPDATE:

After installing lodash via NPM as Sam suggested, this solution worked for me!

Customer.findById(req.params.cust_id).exec(function(err, customer) {
            if (err) return next(err);

            var dog = customer.dogs.id(req.params.dog_id)
            _.merge(dog, req.body);

            customer.save(function(err, customer) {
                if (err) return next(err);
                res.json({
                    message: 'Dog updated.'
                });
            });
        });

the problem here is that your variable dog isn't wrapped with any of mongoose methods because mongoose only wrap the main document.

you could achieve this by using a little library called lodash

like this :

var _ = require('lodash');
exports.update = function(req, res) { 
if(req.body._id) { delete req.body._id; }
  Customer.findById(req.params.id, function (err, customer) {
    if (err) { return handleError(res, err); }
    if(!customer) { return res.send(404); }
    var updated = _.merge(customer, req.body); // lodash merge method update matching fields with the new value
    updated.save(function (err) {
      if (err) { return handleError(res, err); }
      return res.json(200, customer);
    });
  });
};

if its not working the way you want take a look at lodash documentation and also try change the _.merge by _.extend or _.assign

another way to achieve this is by using the operator $addToSet

take a look at the mongo documentation

hope this helps !

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM