Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to update some but not all fields in Mongoose

here is the UserSchema:

var UserSchema = new Schema({
    username: { type: String, required: true, index:{unique: true} },
    firstName: { type: String, required: true },
    lastName: { type: String, required: true },
    email: { type: String, required: true, index:{unique: true} }, 
    password: { type: String, required: true, select: false }
});

Here is the http PUT request:

  // update user information
  api.put('/users/:username', function(req, res) {

    User.findOne({username: req.params.username}, function(err, user) {

      if (err){
        res.send(err);
        return;
      }

      if (!user){
        res.status(404).send({
          success: false,
          message: "user not found"
        });
      } else {
        user.username = req.body.username;
        user.email = req.body.email;
        user.password = req.body.password;
        user.firstName = req.body.firstName;
        user.lastName = req.body.lastName;

        user.save(function(err) {
          if (err){
            res.send(err);
            return;
          }

          res.json({
            success: true,
            message: "user information updated."
          });
        });
      }
    });
  });

The question is, if the user only want to update limited fields, for example, only update username, then the above code does not work, the error looks like this:

{
  "message": "User validation failed",
  "name": "ValidationError",
  "errors": {
    "lastName": {
      "properties": {
        "type": "required",
        "message": "Path `{PATH}` is required.",
        "path": "lastName"
      },
      "message": "Path `lastName` is required.",
      "name": "ValidatorError",
      "kind": "required",
      "path": "lastName"
    },
    "firstName": {
      "properties": {
        "type": "required",
        "message": "Path `{PATH}` is required.",
        "path": "firstName"
      },
.........

so how can I implemement to allow user updates some but not all fields?

Any comments and suggestions are appreciated!

like image 665
leonsPAPA Avatar asked Dec 02 '22 16:12

leonsPAPA


2 Answers

Using findOneAndUpdate with the operator $set in the update object:

User.findOneAndUpdate({username: req.params.username}, { $set: req.body }, { new: true }, callback);

$set will allow you to modify only the supplied fields in the req.body object.

like image 137
Moad Ennagi Avatar answered Dec 31 '22 13:12

Moad Ennagi


This is a good compromise:

Specify the fields that the user can update

let fieldToUpdate = {
    name: req.body.name,
    email: req.body.email,
  };

Then delete all the keys that contains falsy value

  for (const [key, value] of Object.entries(fieldToUpdate)) {
    if (!value) {
      delete fieldToUpdate[key];
    }
  }

Then Update the value using the $set operator

const user = await User.findByIdAndUpdate(
    req.user.id,
    { $set: { ...fieldToUpdate } },
    {
      runValidators: true,
      new: true,
    }
  );
like image 43
Omar De Angelis Avatar answered Dec 31 '22 14:12

Omar De Angelis