skip to Main Content

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


  1. Chosen as BEST ANSWER

    Solved using CHATGPT This is what it replied

    The code you provided appears to be error-free and properly structured. However, I noticed a couple of potential improvements:

    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:

      e.preventDefault();
      try {
        const formData = new FormData();
        formData.append('name', product.name);
        formData.append('description', product.description);
        formData.append('price', product.price);
        formData.append('photo', product.photo);
        formData.append('isShipping', product.isShipping);
        formData.append('category', product.category);
        formData.append('quantity', product.quantity);
    
        const response = await axios.post(
          process.env.REACT_APP_API + 'api/product/create-product',
          formData,
          {
            headers: {
              'Content-Type': 'multipart/form-data',
            },
          }
        );
    
        console.log(response);
        if (response.data.success) {
          toast.success(response.data.message);
        }
      } catch (error) {
        console.log(error);
      }
    }
    

    I checked even while using postman , i was sending data as form data . Replacing this part of code made it worked.


  2. when you pass empty object using post request

      if (!name || !description || !price || !category || !photo || !quantity) {
          return res
            .status(200)
            .json({ success: false, message: "Empty fields found" });
        }
    

    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.

      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();
    

    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.

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