skip to Main Content

I am trying to follow this tutorial about a food ordering website as a beginner and while making the admin panel, I am unable to add the food item I want to submit via the form to the mongoose atlas database that I have setup for it.

Here is the component for adding the food item;

import React, { useState } from "react";
import "./Add.css";
import { assets } from "../../assets/assets";
import axios from "axios"
import { toast } from "react-toastify";

const Add = () => {

  const url = "http://localhost:5173";
  const [image, setImage] = useState(false);
  const [data, setData] = useState({
    name:"",
    description:"",
    price:"",
    category:"Salad"
  })

  const onChangeHandler = (event) => {
    const name = event.target.name;
    const value = event.target.value;
    setData(data =>({...data, [name]:value}))
  }
  
  const onSubmitHandler = async (event) => {
    event.preventDefault();
    const formData = new FormData();
    formData.append("name", data.name)
    formData.append("description", data.description)
    formData.append("price", Number(data.price))
    formData.append("category", data.category)
    formData.append("image", image)
    const response = await axios.post(`${url}/api/food/add`, formData);
    
    if (response.data.success) {
      setData({
        name:"",
        description:"",
        price:"",
        category:"Salad"
      })
      setImage(false)
      toast.success(response.data.message)
    }
    else {
      toast.error(response.data.message)
    }
  } 

  return (
    <div className="add">
      <form className="flex-col" onSubmit={onSubmitHandler}>
        <div className="add-img-upload flex-col">
          <p>Upload Image</p>
          <label htmlFor="image">
            <img src={image?URL.createObjectURL(image):assets.upload_area} alt="" />
          </label>
          <input onClick={(e)=>setImage(e.target.files[0])} type="file" id="image" hidden required />
        </div>
        <div className="add-product-name flex-col">
          <p>Product name</p>
          <input onChange={onChangeHandler} value={data.name} type="text" name="name" placeholder="Type here" />
        </div>
        <div className="add-product-description flex-col">
          <p>Product description</p>
          <textarea onChange={onChangeHandler} value={data.description}
            name="description"
            rows="6"
            placeholder="Write content here"
            required
          ></textarea>
        </div>
        <div className="add-category-price">
          <div className="add-category flex-col">
            <p>Product category</p>
            <select onChange={onChangeHandler} name="category">
              <option value="Salad">Salad</option>
              <option value="Rolls">Rolls</option>
              <option value="Deserts">Deserts</option>
              <option value="Sandwich">Sandwich</option>
              <option value="Cake">Cake</option>
              <option value="Pure Veg">Pure Veg</option>
              <option value="Pasta">Pasta</option>
              <option value="Noodles">Noodles</option>
            </select>
          </div>
          <div className="add-price flex-col">
            <p>Product price</p>
            <input onChange={onChangeHandler} value={data.price} type="Number" name="price" placeholder="$20" />
          </div>
        </div>
        <button type="submit" className="add-btn">ADD</button>
      </form>
    </div>
  );
};

export default Add;

Here is the github repository for what I have done so far, if anyone wants to have a look at the backend.

I think there might be a problem with connecting the admin to the backend or just the admin because when I tried to add the food item to the database using Thunder Client, it worked. I also am clueless about actually where the fault might lie, if it has anything to do with the backend.

Edit: upon performing inspect on the Add.jsx component, the following errors are shown;

No routes matched location "/" 
warning @ react-router-dom

When I try to fill the form the errors are;

POST http://localhost:3000/api/food/add net::ERR_CONNECTION_RESET

and

AxiosError {message: 'Network Error', name: 'AxiosError', code: 'ERR_NETWORK', config: {…}, request: XMLHttpRequest, …}
code
: 
"ERR_NETWORK"

2

Answers


  1. Chosen as BEST ANSWER

    I fixed it! Turns out, I was using onClick for the image upload section on line 56 and onChange for everything else.

    The image was still uploading, but the formData was not getting saved to the Atlas database. I changed it to onChange instead, and it works now. The resulting code snippet being;

    <input onChange={(e)=>setImage(e.target.files[0])} type="file" id="image" hidden />
    

    Thanks for the help!


  2. You are running both admin panel and backend on same URL that is 5173. Host your backend at 3000 or 5000 port and hit to that port from admin.

    Your server code will become: –

    import express from "express";
    import cors from "cors";
    import { connectDB } from "./config/db.js";
    import foodRouter from "./routes/foodRoute.js";
    
    // app comfig
    const app = express();
    const port = 3000;
    
    // middleware
    app.use(express.json());
    app.use(cors());
    
    //db connection
    connectDB();
    
    // api endpoints
    app.use("/api/food", foodRouter);
    app.use("/images", express.static("uploads"));
    
    app.get("/", (req, res) => {
        res.send("API Working");
    });
    
    app.listen(port, () => {
        console.log(`Server Started on http://localhost:${port}`);
    });
    

    And your admin component will become :-

    import React, { useState } from "react";
    import "./Add.css";
    import { assets } from "../../assets/assets";
    import axios from "axios";
    import { toast } from "react-toastify";
    
    const Add = () => {
        const url = "http://localhost:3000";
        const [image, setImage] = useState(false);
        const [data, setData] = useState({
            name: "",
            description: "",
            price: "",
            category: "Salad",
        });
    
        const onChangeHandler = (event) => {
            const name = event.target.name;
            const value = event.target.value;
            setData((data) => ({ ...data, [name]: value }));
        };
    
        const onSubmitHandler = async (event) => {
            event.preventDefault();
            const formData = new FormData();
            formData.append("name", data.name);
            formData.append("description", data.description);
            formData.append("price", Number(data.price));
            formData.append("category", data.category);
            formData.append("image", image);
            const response = await axios.post(`${url}/api/food/add`, formData);
    
            if (response.data.success) {
                setData({
                    name: "",
                    description: "",
                    price: "",
                    category: "Salad",
                });
                setImage(false);
                toast.success(response.data.message);
            } else {
                toast.error(response.data.message);
            }
        };
    
        return (
            <div className="add">
                <form className="flex-col" onSubmit={onSubmitHandler}>
                    <div className="add-img-upload flex-col">
                        <p>Upload Image</p>
                        <label htmlFor="image">
                            <img src={image ? URL.createObjectURL(image) : assets.upload_area} alt="" />
                        </label>
                        <input
                            onClick={(e) => setImage(e.target.files[0])}
                            type="file"
                            id="image"
                            hidden
                            required
                        />
                    </div>
                    <div className="add-product-name flex-col">
                        <p>Product name</p>
                        <input
                            onChange={onChangeHandler}
                            value={data.name}
                            type="text"
                            name="name"
                            placeholder="Type here"
                        />
                    </div>
                    <div className="add-product-description flex-col">
                        <p>Product description</p>
                        <textarea
                            onChange={onChangeHandler}
                            value={data.description}
                            name="description"
                            rows="6"
                            placeholder="Write content here"
                            required
                        ></textarea>
                    </div>
                    <div className="add-category-price">
                        <div className="add-category flex-col">
                            <p>Product category</p>
                            <select onChange={onChangeHandler} name="category">
                                <option value="Salad">Salad</option>
                                <option value="Rolls">Rolls</option>
                                <option value="Deserts">Deserts</option>
                                <option value="Sandwich">Sandwich</option>
                                <option value="Cake">Cake</option>
                                <option value="Pure Veg">Pure Veg</option>
                                <option value="Pasta">Pasta</option>
                                <option value="Noodles">Noodles</option>
                            </select>
                        </div>
                        <div className="add-price flex-col">
                            <p>Product price</p>
                            <input
                                onChange={onChangeHandler}
                                value={data.price}
                                type="Number"
                                name="price"
                                placeholder="$20"
                            />
                        </div>
                    </div>
                    <button type="submit" className="add-btn">
                        ADD
                    </button>
                </form>
            </div>
        );
    };
    
    export default Add;
    

    Hope this helps!

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