'SyntaxError: Unexpected Token P in JSON at position 0 - Error in React.js app

I have created a React.js app which is having backend (MongoDB & Mongoose). In my app i have a signup form component and what i want is when a user clicks the Register button on Signup page all the data in input fields should be stored in my backend. I am using MongoDB-atlas as backend. My backend server is running on port 5000 and Frontend is running on port 3000

i have added this line "proxy": "http://localhost:5000" in my package.json file

When i try to test my project, first i start my both Frontend & backend servers. But when i click the Register button i get 2 errors in console:

1- Proxy error: Could not proxy request /favicon.ico from 127.0.0.1:3000 to http://localhost:5000

2- Uncaught (in promise) SyntaxError: Unexpected Token P in JSON at position 0

Here is the version information i have currently installed:

"react": "^16.13.1",
    "react-dom": "^16.13.1",
    "react-router-dom": "^6.2.1",
    "react-scripts": "3.4.1"

And here is my Signup.jsx file code

import React, {useState} from 'react'
import {NavLink, useNavigate} from 'react-router-dom'

const Signup = () => {
  const navigate = useNavigate()
  const [user, setUser] = useState({
    name: "",
    email: "",
    phone: "",
    work: "",
    password: "",
    cpassword: ""
  })
  let name, value
  const handleInput = (event) => {
    name = event.target.name
    value = event.target.value
    setUser({...user, [name]:value})
  }
  const postData = async (event) => {
    event.preventDefault()
    const {name, email, phone, work, password, cpassword} = user
    const res = await fetch('/register', {
      method: 'POST',
      headers: {
        "Accept": "application/json",
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({name, email, phone, work, password, cpassword})
    })
    const data = await res.json()
    if(data.status === 422 || !data){
      window.alert("Failed to register")
    }else{
      window.alert("Registered successfully please signin")
      navigate('/signin')
    }
  }
  return (
    <>
      <section>
        <h1>Sign up</h1>
        <form method='POST'>
            <input value={user.name} onChange={handleInput} type="text" name="name" placeholder="Your full name"></input>
            <input value={user.email} onChange={handleInput} type="email" name="email" placeholder="Your email"></input>
            <input value={user.phone} onChange={handleInput} type="number" name="phone" placeholder="Your phone number"></input>
            <input value={user.password} onChange={handleInput} type="password" name="password" placeholder="Create a password"></input>
            <input value={user.cpassword} onChange={handleInput} type="password" name="cpassword" placeholder="Please retype your password"></input>
            <input onClick={postData} type="submit" name="signup-btn" value="Register"></input>
        </form>
        <NavLink to="/login">Already have an account - Login</NavLink>
      </section>
    </>
  )
}

export default Signup


Solution 1:[1]

In React we don't generally actually submit forms and allow the default form actions to occur. Move the input/button's onClick={postData} to the form's onSubmit={postData} and prevent the default submit action from occurring.

const Signup = () => {
  const navigate = useNavigate();
  const [user, setUser] = useState({
    name: "",
    email: "",
    phone: "",
    work: "",
    password: "",
    cpassword: ""
  });

  const handleInput = (event) => {
    const { name, value } = event.target;
    setUser({ ...user, [name]: value });
  };

  const postData = async (event) => {
    event.preventDefault();
    const { name, email, phone, work, password, cpassword } = user;
    try {
      const res = await fetch('/register', {
        method: 'POST',
        headers: {
          "Accept": "application/json",
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({ name, email, phone, work, password, cpassword })
      })
      const data = await res.json();
      if (data.status === 422 || !data) {
        window.alert("Failed to register");
      } else {
        window.alert("Registered successfully please signin");
        navigate('/signin');
      }
    } catch(error) {
      // handle any rejected fetch Promises and other errors
    }
  };

  return (
    <section>
      <h1>Sign up</h1>
      <form onSubmit={postData}>
        <input value={user.name} onChange={handleInput} type="text" name="name" placeholder="Your full name" />
        <input value={user.email} onChange={handleInput} type="email" name="email" placeholder="Your email" />
        <input value={user.phone} onChange={handleInput} type="number" name="phone" placeholder="Your phone number" />
        <input value={user.password} onChange={handleInput} type="password" name="password" placeholder="Create a password" />
        <input value={user.cpassword} onChange={handleInput} type="password" name="cpassword" placeholder="Please retype your password" />
        <input type="submit" name="signup-btn" value="Register" />
      </form>
      <NavLink to="/login">Already have an account - Login</NavLink>
    </section>
  )
}

Solution 2:[2]

Agree with Drew's opinion, let React synthetic events do their job. However, the error is happening in your server response. Once you trigger the API call, this line is expecting a valid JSON to be parsed as an object

  const data = await res.json() // Not JSON? Error then

Try to debug in the console or network tab what is the request returning based on that API call

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Drew Reese
Solution 2 teo-garcia