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
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!
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.Sorting in Mongo
ObjectId in Mongo