Why is my react form not working as it should?

Viewed 38

I'm trying to send data to my database using a react form and it's not working as it should. When I click the button, the function handleSubmit is called but it gets an error for some reason.

This is the error I see in the console when I click the button:

enter image description here

Here is the code for the react form:

import { useState } from "react";

const ProjectAdminForm = () => {
    const [sdg_desc, setSDGDesc] = useState('')
    const [sdg_num, setSDGNum] = useState('')
    const [goal, setGoal] = useState('')
    const [orginization, setOrginization] = useState('')
    const [source, setSource] = useState('')
    const [location, setLocation] = useState('')
    const [published, setPublished] = useState('')
    const [website_url, setWebsiteURL] = useState('')
    const [assignment_type, setAssignmentType] = useState('')
    const [sharepoint_link, setSharepointLink] = useState('')
    const [statement, setStatement] = useState('')
    const [error, setError] = useState(null)

    const handleSubmit = async (e) => {
        e.preventDefault() // Prevents refresh of page from happening

        console.log('button clicked')
        const project = {sdg_desc, sdg_num, goal, orginization, source, location, published, website_url, assignment_type, sharepoint_link, statement}
                        
        // Sending form response to backend
        const response = await fetch('/api/projects', {
            method: 'POST',
            body: JSON.stringify(project),
            headers: {
                'Content-Type': 'application/json'
            }
        })
        const json = await response.json
        

        // Checking for error
        if (!response.ok) {
            setError(json.error)
        }
        if (response.ok) {
            // Reset form inputs back to empty string
            setSDGDesc('')
            setSDGNum('')
            setGoal('')
            setOrginization('')
            setSource('')
            setLocation('')
            setPublished('')
            setWebsiteURL('')
            setAssignmentType('')
            setSharepointLink('')
            setStatement('')
            
            setError(null)
            console.log('new project added', json)
        }
    }

    return (
        <form className="create" onSubmit={handleSubmit}>
            <h3>Add a New Project</h3>

            <label>SDG Name:</label>
            <input 
                type="text"
                onChange={(e) => setSDGDesc(e.target.value)}
                value={sdg_desc}
            />

            <label>SDG Num:</label>
            <input 
                type="text"
                onChange={(e) => setSDGNum(e.target.value)}
                value={sdg_num}
            />

            <label>Goal:</label>
            <input 
                type="text"
                onChange={(e) => setGoal(e.target.value)}
                value={goal}
            />

            <label>Orginization:</label>
            <input 
                type="text"
                onChange={(e) => setOrginization(e.target.value)}
                value={orginization}
            />

            <label>Source:</label>
            <input 
                type="text"
                onChange={(e) => setSource(e.target.value)}
                value={source}
            />

            <label>Location:</label>
            <input 
                type="text"
                onChange={(e) => setLocation(e.target.value)}
                value={location}
            />

            <label>Published:</label>
            <input 
                type="text"
                onChange={(e) => setPublished(e.target.value)}
                value={published}
            />

            <label>Website URL:</label>
            <input 
                type="text"
                onChange={(e) => setWebsiteURL(e.target.value)}
                value={website_url}
            />

            <label>Assignment Type:</label>
            <input 
                type="text"
                onChange={(e) => setAssignmentType(e.target.value)}
                value={assignment_type}
            />

            <label>Sharepoint Link:</label>
            <input 
                type="text"
                onChange={(e) => setSharepointLink(e.target.value)}
                value={sharepoint_link}
            />

            <label>Statement:</label>
            <input 
                type="text"
                onChange={(e) => setStatement(e.target.value)}
                value={statement}
            />

            <button>Add Project</button>
            {error && <div className="error">{error}</div>}
        </form>
    )
}

export default ProjectAdminForm

Here is the code of the backend api it points too:

// create new project
const createProject = async (req, res) => {
    // adding in a new project
    const {sdg_desc, sdg_num, goal, orginization, source, location, published, website_url, assignment_type, sharepoint_link, statement} = req.body
    try {
        const project  = await Project.create({sdg_desc, sdg_num, goal, orginization, source, location, published, website_url, assignment_type, sharepoint_link, statement})
        res.status(200).json(project)
    } catch (error) {
        res.status(400).json({error: error.message})
    }
}

Could someone tell me why when I click the "Add Project" button I get this error?

3 Answers

There are multiple problems. I am gonna assume you are using MongoDB and mongoose, so your code for backend should look like this.

const createProject = async (req, res) => {

 const {sdg_desc, sdg_num, goal, orginization, source, location, published, website_url, assignment_type, sharepoint_link, statement} = req.body

const newProject = new Project{(
     sdg_desc: sdg_desc,
     sdg_num : sdg_num,
     goal : goal,
     orginization : orginization,
     source : source,
     location : location,
     published : published,
     website_url : website_url,
     assignment_type : assignment_type,
     sharepoint_link : sharepoint_link,
     statement : statement
)};
    try {
        await newProject.save();
    } catch (error) {
        res.status(500).json({error: error.message})
    }

    res.status(201).json({project: newProject});
}

And on the frontend when you are using the fetch API, you need to specify full link to the backend, so it should look like this

const response = await fetch('http://localhost:8000/api/projects', {
            method: 'POST',
            body: JSON.stringify(project),
            headers: {
                'Content-Type': 'application/json'
            }
        })

Also make sure that the data you are sending to the backend have the same name on the frontend

<button>Add Project</button>

Should be

<button onClick={handleSubmit}>Add Project</button>

or

<button onClick={()=>handleSubmit()}>Add Project</button>

You don’t call your function for some reason

I think you can work it out with form like that (but honestly I haven’t seen even single time somebody does it like that in react) but then you have to give something like:

<button type=“submit”>…

So also I would refactor a bit your bunch of setState:

const [state,setState] = useState({});
const handleInputChange = (e) => setState({…state, [e.target.name]:e.target.value});

On inputs:
<input name=“project” onChange={handleInputChange}>…</input>

This will give much more flexible state with less code

You should add console.log(req.body) This would point to source of error

Looks like the problem is coming from your backend, are you using any middlewares, validators like Joi ?

Related