Home > OS >  update controller fails to works as intended
update controller fails to works as intended

Time:01-02

I'm trying to make a nodejs\ExpressJs backend for a small project. The backend is split into services, controllers and router files. While testing the updateProduct (to update the fields of a product that already exists in database) function on postman using a x-www-form-urlencoded body, I got the following error:

{
    "err": {
        "stringValue": "\"{ name: 'Hp', description: 'Pavillion', price: '20000' }\"",
        "valueType": "Object",
        "kind": "ObjectId",
        "value": {
            "name": "Hp",
            "description": "Pavillion",
            "price": "20000"
        },
        "path": "_id",
        "reason": {},
        "name": "CastError",
        "message": "Cast to ObjectId failed for value \"{ name: 'Hp', description: 'Pavillion', price: '20000' }\" (type Object) at path \"_id\" for model \"Product\""
    }
}

Screen of postman form : enter image description here This is the code I used in their respective files, I tried logging a message into the console to see whether they are called upon, and yes they were called as intended.

//service file
const updateProduct = async(product)=>{
    return await Product.findByIdAndUpdate(product._id, product)
}

//controller file
const updateProduct = async(req, res)=>{
    try{
        const result = await productService.updateProduct(req.body)
        res.status(200).json(result)
    }
    catch(error){
        res.status(500).json({err:error})
    }
}

//router file
router.put("/:id", productController.updateProduct)

I tried changing the code in the service layer to the following, it didn't work, but it not generate the same problem.

const updateProduct = async(product) => {
  return await Product.findByIdAndUpdate(
    product._id,
    {
      $set: {
        name: product.name,
        price: product.price,
        description: product.description
      }
    },
    { new: true }
  );
};

If relevant I'm using Mongoose and other methods such as adding or deleting work as intended. Thanks

CodePudding user response:

Problem:

You have to get the _id of the desired product from the params not from the req.body which return null like:

this:

return await Product.findByIdAndUpdate(product._id, product);

would turn into:

return await Product.findByIdAndUpdate(undefined, {
            "name": "Hp",
            "description": "Pavillion",
            "price": "20000"
})

and of course, the record won't get updated.

Solution:

your controller should look like this (I've used the path):

//controller file
const updateProduct = async(req, res)=>{
    try{
        const result = await productService.updateProduct(req.params.id, req.body)
        res.status(200).json(result)
    }
    catch(error){
        res.status(500).json({err:error})
    }
}

and your service should look like this:

//service file
const updateProduct = async(id, product)=>{
    return await Product.findByIdAndUpdate(id, product)
}
``
  • Related