Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose update an item from array by id

In a node js project, where I use mongoose, I'm trying to update an item of array inside a document.
I have a users schema which has a notifications array inside. Each user has an _id and each notifications item has an _id.

How can update a notification by, user id and notification id?

USER SCHEMA:

const schema = mongoose.Schema({
  notifications: [{
    id: { type: mongoose.Schema.ObjectId },
    title: { type: String },
    body: { type: String },
    isRead: { type: Boolean, default: false },
    date: { type: Date }
  }],
  token: { type: String },
  isActive: { type: Boolean, default: false }
}, { timestamps: {} }) 

This is what I've tried so far:

exports.updateNotification = (req, res) => {

  // Note: in req.params I receive id(for user id) and notificationId.

  UserModel.findByIdAndUpdate(req.params.id, { $set: { notifications: req.body } }, { safe: true, upsert: true, new: true })
    .then((result) => res.status(201).json({
      success: true,
      message: res.__('success.add'),
      user: result
    }))
    .catch(err => errorHandler.handle(err, res))
}

The method findByIdAndUpdate I've used it to updated the user, but I don't know how to adapt it for updating a notification, by id.

like image 699
V. Sambor Avatar asked Feb 12 '18 08:02

V. Sambor


2 Answers

Try using $elemMatch,

UserModel.findOneAndUpdate({_id: 1, notifications: {$elemMatch: {id: 2}}},
                           {$set: {'notifications.$.title': req.body.title,
                                   'notifications.$.body': req.body.body,}}, // list fields you like to change
                           {'new': true, 'safe': true, 'upsert': true});
like image 103
ViKiG Avatar answered Sep 21 '22 14:09

ViKiG


UserModel.update({'_id':1,'notifications.id': 2}, {'$set': {
    'notifications.$.title': 'updated title',
    'notifications.$.body': 'updated body'
}}, function(err) { ...}

Haven't tested but this should work.

like image 30
Ridham Tarpara Avatar answered Sep 18 '22 14:09

Ridham Tarpara