How to update a document in mongodb with NodeJS

I’m trying to update a value for MongoDB using NodeJS this is my code:

Controller.js

    updateProduct: async (req, res) => {
        try {
            const { params: { id } } = req;
            const { body } = req;
            if (!body || Object.keys(body).length === 0) {
                Response.ERROR(res, new createError.BadRequest());
            } else {
            let product = await ProductsService.updateP(id, body);
        }
            if (!product) {
                Response.ERROR(res, new createError.NotFound());
            
            } else {
                Response.SUCCSESS(res, 201, `Producto actualizado`, product);
            }
        } catch (error) {
            debug(error);
            Response.ERROR(res);
        }
    },

Services.js

const updateP = async (id, product) => {
    const collection = await Database(COLLECTION);
    return collection.updateOne({_id: new ObjectId(id)}, { $set: { ...product } })
    
};

DB

 "body": {
        "_id": "651cd5d91e3c20bda7cea881",
        "name": "shoes",
        "price": 359,
        "quantity": 10,
    }

I got this error:

MongoServerError: Performing an update on the path '_id' would modify the immutable field '_id'

I have investigate and tried to change ...product for req.params.name, but it doesn’t work

I’d like to get something like that:

 "body": {
        "_id": "651cd5d91e3c20bda7cea881",
        "name": "Coca-cola",
        "price": 359,
        "quantity": 10,
    }

>Solution :

The error you are encountering arises because MongoDB does not allow the modification of the _id field of a document once it has been created. It’s an immutable field.

In your update function, you’re trying to update the document using the spread operator (...product) which spreads all the fields, including _id, from product into the update object. This is why you’re seeing the error.

To resolve the issue, you should remove the _id field from the product object before you attempt the update:

const updateP = async (id, product) => {
    const collection = await Database(COLLECTION);
    const { _id, ...updateData } = product;  // Remove _id from product
    return collection.updateOne({ _id: new ObjectId(id) }, { $set: updateData });
};

By destructuring the product object in this way, you’re essentially extracting the _id field and the remaining data (which doesn’t include _id) is stored in updateData. This updateData object can then safely be used in the $set operator without attempting to modify the _id field.

Leave a Reply