skip to Main Content

I have a code where a schema for storing information about product has been defined followed by the code to add product information. Here is the code:

const Product=mongoose.model("Product", {
    id:{
        type: Number, 
        required: true,
    },
    name:{
        type: String,
        required: true,
    },
    image:{
        type: String,
        required: true,
    },
    category:{
        type: String,
        required: true,
    },
    new_price:{
        type: Number,
        required: true,
    },
    old_price:{
        type: Number,
        required: true,
    },
    date:{
        type: Date,
        default: Date.now,
    },
    available:{
        type: Boolean,
        default: true,
    },
})

app.post('/addproduct', async (req, res)=>{
    let products = await Product.find({});
    let id;
    if (products.length>0){
        let last_product_array = products.slice(-1);
        let last_product = last_product_array[0];
        id = last_product.id+1;
    }
    else{
        id=1;
    }
    const product = new Product({
        id: id,
        name: req.body.name,
        image: req.body.image,
        category: req.body.category,
        new_price: req.body.new_price,
        old_price: req.body.old_price,
    });
    console.log(product);
    await product.save();
    console.log("Saved");
    res.json({
        success: true,
        name: req.body.name,
    })
})

Here is the code from front-end where I am making the request:

    const AddProduct = () => {

  const [image, setImage] = useState(false);
  const [productDetails, setProductDetails] = useState({
    name:"",
    image: "",
    category: "women",
    new_price:"",
    old_price: ""
  })

  const imageHandler = (e)=>{
     setImage(e.target.files[0]);

  }
  const changeHandler = (e) =>{
    setProductDetails({...productDetails, [e.target.name]:[e.target.value]})
  }

  const Add_Product = async () =>{
        console.log(productDetails)
        
        let responseData;
        let product = productDetails;

        let formData = new FormData();
        formData.append('product', image);
        await fetch('http://localhost:4000/upload',{
            method: 'POST',
            headers: {
                Accept: 'application/json',
            },
            body: formData,
        }).then((resp)=>resp.json()).then((data)=>{responseData=data});
        if (responseData.success)
        {
            product.image=responseData.image_url;
            console.log(product);
            
            await fetch('http://localhost:4000/addproduct', {
                method: 'POST',
                headers:{
                    Accept:'application/json',
                    'Content-Type': 'application/json',
                },
                body: JSON.stringify(product),
            }).then((resp)=>resp.json()).then((data)=>{
                data.success?alert("Product added"):alert("Failed")
            })
        }
        
  }

  return (
    <div className='add-product'>
        <div className='addproduct-itemfield'>
            <p>Product title</p>
            <input value={productDetails.name} onChange={changeHandler} type="text" name='name' placeholder='Type here'/>
        </div>
        <div className='addproduct-price'>
            <div className='addproduct-itemfield'>
                <p>Price</p>
                <input value={productDetails.old_price} onChange={changeHandler} type="text" name='old_price' placeholder='Type here'/>
            </div>
            <div className='addproduct-itemfield'>
                <p>Offer Price</p>
                <input value={productDetails.new_price} onChange={changeHandler} type="text" name='new_price' placeholder='Type here'/>
            </div>
        </div>
        <div className='addproduct-itemfield'>
            <p>Product Category</p>
            <select value={productDetails.category} onChange={changeHandler} name='category' className='add-product-selector'>
                <option value="women">Women</option>
                <option value="men">Men</option>
                <option value="kids">Kids</option>
            </select>
        </div>
        <div className='addproduct-itemfield'>
            <label htmlFor='file-input'>
                <img src = {image?URL.createObjectURL(image):upload_area} className='addproduct-thumbnail-img' alt= ""/>
            </label>
            <input onChange={imageHandler} type="file" name='image' id='file-input' hidden/>
        </div>
        <button onClick={()=>{Add_Product()}} className='addproduct-btn'>ADD</button>
    </div>
  )
}

export default AddProduct

While executing the code, it is generating the following error:

this.$__.validationError = new ValidationError(this);
                               ^
ValidationError: Product validation failed: name: Cast to string failed for value "[ 'kids357' ]" (type Array) at path "name", category: Cast to string failed for value "[ 'kids' ]" (type Array) at path "category", new_price: Cast to Number failed for value "[ '65' ]" (type Array) at path "new_price", old_price: Cast to Number failed for value "[ '100' ]" (type Array) at path "old_price"
    at Document.invalidate (C:UsersrafizDocumentsLearningReactJSE-Commercebackendnode_modulesmongooselibdocument.js:3201:32)       
    at model.$set (C:UsersrafizDocumentsLearningReactJSE-Commercebackendnode_modulesmongooselibdocument.js:1460:12)
    at model.$set (C:UsersrafizDocumentsLearningReactJSE-Commercebackendnode_modulesmongooselibdocument.js:1115:16)
    at model.Document (C:UsersrafizDocumentsLearningReactJSE-Commercebackendnode_modulesmongooselibdocument.js:166:12)
    at model.Model (C:UsersrafizDocumentsLearningReactJSE-Commercebackendnode_modulesmongooselibmodel.js:131:12)
    at new model (C:UsersrafizDocumentsLearningReactJSE-Commercebackendnode_modulesmongooselibmodel.js:4700:15)
    at C:UsersrafizDocumentsLearningReactJSE-Commercebackendindex.js:87:21
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5) 
.
.
.
.
{
        generatedMessage: true,
        code: 'ERR_ASSERTION',
        actual: false,
        expected: true,
        operator: '=='
      },
      valueType: 'Array'
    }
  },
  _message: 'Product validation failed'

How to resolve this error?

I tried to write code for admin panel of a e-commerce website. It should insert the product information into MongoDB collection.

2

Answers


  1. Chosen as BEST ANSWER

    Actually I am following a video tutorial (youtube.com/watch?v=y99YgaQjgx4) and writing exactly the same code. For this same code, those values were sent as strings but for me, these are being sent as arrays. I have watched the video again and again to check whether I have made any mistake, but I couldn't find any error. That's why, I have added the code from front-end where the request is being made. Please help me to identify why the values are being sent as arrays instead of strings. Thanks in advance!


  2. From the error you have added, it seems like the payload you have passed is incorrect since all the values are coming into an array format. You have specified string for a name, but the value it received is array. And that goes for all the fields. Do check the req.body for the payload received from the client side.

    Also a small change in your code.
    It seems you’re adding 1 to the id field. Instead of going through the array.length, you can use countDocuments() to get the count. Optionally, since you’re already storing id of the item, you can get the id of the last document added and do +1 on it.

    The _id field consists of timestamp, which can be used to fetch the last document.
    1 is used for sorting in ascending and -1 for descending.

        let product = await Product.find({}).sort({_id: -1});
        let id = product.id + 1
        
    

    Sorting in Mongo

    ObjectId in Mongo

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search