I am working on a ecommerce project and currently working on create product page , when i send a empty post request to backend , it returns back some response , but when i add the product , it gets stuck… means no response back .
Here is my frontend and backend code
//Create_Product.jsx
import React, { useEffect, useState } from "react";
import AdminMenu from "../../components/AdminMenu";
import Layout from "../../components/Layout/Layout";
import axios from "axios";
import { Select } from "antd";
import { toast } from "react-toastify";
const { Option } = Select;
export default function CreateProduct() {
const [category, setCategory] = useState("");
const [categories, setCategories] = useState([]);
const [product, setProduct] = useState({
name: "",
description: "",
price: "",
photo: "",
isShipping: "",
category: "",
quantity: "",
});
useEffect(() => {
getAllCategories();
}, []);
async function getAllCategories() {
try {
const { data } = await axios.get(
process.env.REACT_APP_API + "api/category/get-category"
);
if (data.success) setCategories(data.data);
} catch (e) {
toast.error("Something went wrong while fetching Categories");
console.log(e);
}
}
async function handleOnClick(e) {
e.preventDefault();
try {
const response = await axios.post(
process.env.REACT_APP_API + "api/product/create-product",
product
);
if (response.data.success) {
toast.success(response.data.message);
}
} catch (error) {
console.log(error);
}
}
// console.log(product);
function handleOnChange(e) {
const { name, value } = e.target;
if (name === "photo") {
const file = e.target.files[0];
if (file) {
setProduct((prevValue) => {
return { ...prevValue, photo: file };
});
}
} else {
setProduct((prevValue) => {
return { ...prevValue, [name]: value };
});
}
}
return (
<Layout>
<div className="container-fluid">
<div className="row">
<div className="col-md-3">
<AdminMenu />
</div>
<div className="col-md-9">
<h2 className="mb-2">Create Product</h2>
<Select
showSearch
showArrow
placeholder="Select Category"
className="w-50 "
onChange={(value) =>
setProduct((prevValue) => ({
...prevValue,
category: value,
}))
}
>
{categories?.map((item, i) => {
return (
<Option key={i} value={item._id}>
{item.name}
</Option>
);
})}
</Select>
<div className="mb-2">
{product.photo && (
<div className="text-left">
<img
src={URL.createObjectURL(product.photo)}
className="img img-responsive"
height={"200px"}
alt="product-photo"
/>
</div>
)}
</div>
<div className="mb-2">
<label className="btn btn-outline-secondary mt-2">
{" "}
{product.photo ? product.photo.name : "Upload Photo"}
<input
type="file"
name="photo"
accept="image/*"
hidden
onChange={handleOnChange}
/>
</label>
</div>
<div className="mb-2">
<form>
<div className="form-group">
<label htmlFor="exampleInputEmail1">Product Name</label>
<input
type="text"
className="form-control mb-2 w-50"
placeholder="Enter product name"
value={product.name}
name="name"
onChange={handleOnChange}
/>
</div>
<div className="form-group">
<label htmlFor="description">Description</label>
<textarea
type="text"
name="description"
className="form-control mb-2 w-50"
rows={3}
placeholder="Description"
value={product.description}
onChange={handleOnChange}
/>
</div>
<div className="form-group">
<label htmlFor="exampleInputEmail1">Product price</label>
<input
type="text"
className="form-control mb-2 w-50"
placeholder="Price"
value={product.price}
name="price"
onChange={handleOnChange}
/>
</div>
<div className="form-group">
<label htmlFor="exampleInputEmail1">Product quantity</label>
<input
type="text"
className="form-control mb-2 w-50"
placeholder="Quantity"
value={product.quantity}
name="quantity"
onChange={handleOnChange}
/>
</div>
<div className="form-group">
<label htmlFor="Shipping">Shipping ?</label>
<Select
placeholder="Is product shipping available"
className="w-50 form-control mb-4"
onChange={(value) =>
setProduct((prevValue) => ({
...prevValue,
isShipping: value,
}))
}
name="isShipping"
>
<Option value={true}>TRUE</Option>
<Option value={false}>FALSE</Option>
</Select>
</div>
<div className="form-group">
<button
type="submit"
className="btn btn-success"
onClick={handleOnClick}
>
Create product
</button>
</div>
</form>
</div>
</div>
</div>
</div>
</Layout>
);
}
//Here is my backend code
in router in first check if user is signed in , then checks for admin and then uses formidable middleware
router.post('/create-product',requireSignIn,isAdmin,formidable(),createProductController);
//Main controller code
import slugify from "slugify";
import Product from "../../model/productModel.js";
import fs from "fs";
export default async function createProductController(req, res) {
try {
console.log("I am triggered");
const { name, description, price, category, isShipping , quantity } = req.fields;
console.log( name, description, price, category, isShipping , quantity);
const { photo } = req.files;
if (!name || !description || !price || !category || !photo || !quantity) {
return res
.status(200)
.json({ success: false, message: "Empty fields found" });
}
if (photo.size > 100000) {
return res
.status(200)
.json({ success: false, message: "Photo size limit crossed" });
}
const product = new Product({
...req.fields,
slug: slugify(name),
})
if (photo) {
product.photo.data = fs.readFileSync(photo.path);
product.photo.contentType = photo.type;
}
await product.save();
return res
.status(200)
.json({ success: true, message: "Product created successfully" });
} catch (e) {
console.log(e);
return res
.status(500)
.json({ success: false, message: "Error in product creation", e });
}
}
I tried to add product to my mongodb server using react frontend and node backend and got stuck ! please help
2
Answers
Solved using CHATGPT This is what it replied
File Upload: When uploading files using , the file data is stored in the event.target.files array. In your handleOnChange function, you are correctly retrieving the file using e.target.files[0]. However, you are directly assigning the entire file object to the photo field in the product state. It's important to note that you cannot directly send a file object in a JSON request. Instead, you should convert the file object to a FormData object to handle file uploads properly. Here's an updated version of the handleOnClick function to handle file uploads using FormData:
I checked even while using postman , i was sending data as form data . Replacing this part of code made it worked.
when you pass empty object using post request
this part of the code gets triggered so you are getting response. But when you pass some data below is the code that is getting executed.
I suggest you to debug this code check if it is taking time to execute and also check if there is any error with this. I am not able to give more info due lack context of your problem.