Home > OS >  Duplicate key error when performing update Express Mongoose
Duplicate key error when performing update Express Mongoose

Time:02-21

I have a field called mail as unique in MongoDB.

I'm trying to update the user but it happens that if I don't change the mail field it tells me it's a duplicate. I need it not to be necessary to always change the email because sometimes they just want to change another field.

This is my model:


import { Schema, model } from "mongoose";

const UserSchema = Schema (
  {
    username: {
        type: String,
        maxlength:50,
        required: [true, 'El Nombre de Usuario es obligatorio'],
        unique: true
    },
    name: {
        type: String,
        maxlength:50,
        required: [true, 'El Nombre es obligatorio']
    },
    lastName: {
        type: String,
        maxlength:50,
        required: [true, 'El Apellido es obligatorio']
    },
    mail: {
        type: String,
        required: [true, 'El Correo es obligatorio'],
        unique: true
    },   
    password: {
        type: String,
        required: [true, 'La Contraseña es obligatorio']
    },
    picture:{
        path: {
            type: String
        },
        originalName: {
            type: String
        }
        
    },
    role: {
        type: String,
        required: true,
        enum: ['ADMIN_ROLE', 'USER_ROLE', 'SUPER_ROLE', 'SELLER_ROLE', 'WAREHOUSE_ROLE', 'WAREHOUSE_ASSISTANT_ROLE', 'SALES_ROLE', 'PURCHASES_ROLE','CASH_ROLE'] 
    },
    status: {
        type: Boolean,
        default: true
    },
    createdBy:{
        uid : { type: String, required: true },
        username:{ type: String, required: true }
    },
    createdAt: {
        type: Date,
        default: Date.now
    }
  }  
);

module.exports = model('Users', UserSchema);

This is my function where I update but it returns the error of duplicate key in mail.

const updateUser = async (req, res = response) => {

    let id = req.params.id;

    let { _id, password,  ...data } = req.body;

    if ( password ) {

        let salt = bcrypt.genSaltSync(15);
        resto.password = bcrypt.hashSync( password, salt );   
    }

    let lastModificationByUser = {
        uid: req.uid,
        username: req.user.username,
        comments: data.comments
    };

    let user = await User.findByIdAndUpdate( id,
        {
            $set: data, 
            $push: { 
                'lastModificationBy': {
                  $each: [lastModificationByUser],
                  $slice: -5 
                }
            }
        },{ new: true }
    );

    res.json({
        user
    })
}

But I get the following error:

error image

Thanks for your help.

CodePudding user response:

Understand unique

  1. if you create a user with a unique email address and then update their email address to a non-unique value (same email address), you'll get the dup key error.

  2. if you insert a user with the email address empty, and you try to create another user with the email address empty, you will also get the dup error.

In your case

Remove the mail field from your data object, unless you are updating the user with a new unique email address.

DO NOT TRUST ANYTHING SUBMITTED CLIENT SIDE

let { _id, password,  ...data } = req.body;

Destructuring and then updating the data field directly to the model is not safe. (e.g. even if your form does not contain the password field)

For example, I can send a post request with curl or postman with the password field, and you will be updating the password too without knowing.

What you should do

const { name, lastname, picture } = data;

const update = { name, lastname, picture }

let user = await User.findByIdAndUpdate( id, update );

PS: this is just an example, though in your codes you already conditionally check your password.

  • Related