'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 |
