'Uncaught (in promise) SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data - REACT
So I've been trying to create this "register" user with the MERN stack. But in the console, I see an error that is very difficult for me to understand. I don't really understand where the error is exactly.
It says Uncaught (in promise) SyntaxError: JSON.parse: unexpected character at line 1 column 1 of the JSON data
but I don't understand where that is. Can someone enlighten me please?
This is my server index.js
const express = require("express");
const app = express();
const cors = require("cors");
const mongoose = require("mongoose");
const User = require("./models/user.model");
const jwt = require("jsonwebtoken");
const bcrypt = require("bcryptjs");
app.use(cors());
app.use(express.json());
mongoose.connect("mongodb://localhost:27017/tribeto");
app.post("/api/register", async (req, res) => {
console.log(req.body);
try {
const newPassword = await bcrypt.hash(req.body.password, 10);
await User.create({
companyName: req.body.companyName,
firstName: req.body.firstName,
lastName: req.body.lastName,
jobTitle: req.body.jobTitle,
email: req.body.email,
phone: req.body.phone,
password: newPassword,
});
res.json({ status: "ok" });
} catch (err) {
res.json({ status: "error", error: "Duplicate email" });
}
});
app.post("/api/login", async (req, res) => {
const user = await User.findOne({
email: req.body.email,
});
if (!user) {
return { status: "error", error: "Invalid login" };
}
const isPasswordValid = await bcrypt.compare(
req.body.password,
user.password
);
if (isPasswordValid) {
const token = jwt.sign(
{
name: user.name,
email: user.email,
},
"secret123"
);
return res.json({ status: "ok", user: token });
} else {
return res.json({ status: "error", user: false });
}
});
app.get("/api/quote", async (req, res) => {
const token = req.headers["x-access-token"];
try {
const decoded = jwt.verify(token, "secret123");
const email = decoded.email;
const user = await User.findOne({ email: email });
return res.json({ status: "ok", quote: user.quote });
} catch (error) {
console.log(error);
res.json({ status: "error", error: "invalid token" });
}
});
app.post("/api/quote", async (req, res) => {
const token = req.headers["x-access-token"];
try {
const decoded = jwt.verify(token, "secret123");
const email = decoded.email;
await User.updateOne({ email: email }, { $set: { quote: req.body.quote } });
return res.json({ status: "ok" });
} catch (error) {
console.log(error);
res.json({ status: "error", error: "invalid token" });
}
});
app.listen(3000, () => {
console.log("Server started on 3000");
});
And here is the user.model.js that I'm using:
const mongoose = require("mongoose");
const User = new mongoose.Schema(
{
companyName: { type: String, required: true, unique: true },
firstName: { type: String, required: true },
lastName: { type: String, required: true },
jobTitle: { type: String, required: true },
email: { type: String, required: true, unique: true },
phone: { type: String, required: true },
password: { type: String, required: true },
},
{ collection: "user-data" }
);
const model = mongoose.model("UserData", User);
module.exports = model;
And here is the implementation in my component:
import React, { useState } from "react";
import { ChevronRightIcon } from "@heroicons/react/solid";
export default function Example() {
const [companyName, setCompanyName] = useState("");
const [firstName, setFirstName] = useState("");
const [lastName, setLastName] = useState("");
const [jobTitle, setJobTitle] = useState("");
const [email, setEmail] = useState("");
const [phone, setPhone] = useState("");
const [password, setPassword] = useState("");
async function registerUser(event) {
event.preventDefault();
const response = await fetch("http://localhost:3000/api/register", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
companyName,
firstName,
lastName,
jobTitle,
email,
phone,
password,
}),
});
const data = await response.json();
}
return (
<div className="relative bg-gray-50 dark:bg-gray-900 overflow-hidden">
<div
className="hidden sm:block sm:absolute sm:inset-0"
aria-hidden="true"
>
<svg
className="absolute bottom-0 right-0 transform translate-x-1/2 mb-48 text-gray-700 lg:top-0 lg:mt-28 lg:mb-0 xl:transform-none xl:translate-x-0"
width={364}
height={384}
viewBox="0 0 364 384"
fill="none"
>
<defs>
<pattern
id="eab71dd9-9d7a-47bd-8044-256344ee00d0"
x={0}
y={0}
width={20}
height={20}
patternUnits="userSpaceOnUse"
>
<rect x={0} y={0} width={4} height={4} fill="currentColor" />
</pattern>
</defs>
<rect
width={364}
height={384}
fill="url(#eab71dd9-9d7a-47bd-8044-256344ee00d0)"
/>
</svg>
</div>
<div className="relative pt-6 pb-16 sm:pb-24">
<main className="mt-24">
<div className="mx-auto max-w-7xl">
<div className="lg:grid lg:grid-cols-12 lg:gap-8">
<div className="px-4 sm:px-6 sm:text-center md:max-w-2xl md:mx-auto lg:col-span-6 lg:text-left lg:flex lg:items-center">
<div>
<a
href="/partner"
className="inline-flex items-center text-white bg-gray-900 rounded-full p-1 pr-2 sm:text-base lg:text-sm xl:text-base hover:text-gray-200"
>
<span className="px-3 py-0.5 text-white text-xs font-semibold leading-5 uppercase tracking-wide bg-btncolor rounded-full">
Become a Partner
</span>
<span className="ml-4 text-sm">Visit our partner page</span>
<ChevronRightIcon
className="ml-2 w-5 h-5 text-gray-500"
aria-hidden="true"
/>
</a>
<h1 className="mt-4 text-4xl tracking-tight font-extrabold text-gray-900 dark:text-white sm:mt-5 sm:leading-none lg:mt-6 lg:text-5xl xl:text-6xl">
<span className="md:block">Credibility through</span>{" "}
<span className="text-primary md:block">Transparency</span>
</h1>
<p className="mt-3 text-base text-gray-900 dark:text-gray-300 sm:mt-5 sm:text-xl lg:text-lg xl:text-xl">
Tribeto transforms the way companies interact with their
customers through video reviews.
</p>
</div>
</div>
<div className="mt-16 sm:mt-24 lg:mt-0 lg:col-span-6">
<div className="bg-white dark:bg-gray-800 sm:max-w-md sm:w-full sm:mx-auto sm:rounded-lg sm:overflow-hidden drop-shadow-lg">
<div className="px-4 py-8 sm:px-10">
<div>
<p className="text-2xl m-2 text-center font-bold text-gray-700 dark:text-white">
Create an account for free
</p>
<p className="text-sm text-center font-medium text-gray-700 dark:text-white">
And feel the power of video reviews today.
</p>
</div>
<div className="mt-6 relative">
<div
className="absolute inset-0 flex items-center"
aria-hidden="true"
>
<div className="w-full border-t border-gray-300 dark:border-gray-600" />
</div>
<div className="relative flex justify-center text-sm"></div>
</div>
<div className="mt-6">
<form onSubmit={registerUser} className="space-y-6">
<div>
<label htmlFor="company-name" className="sr-only">
Company name
</label>
<input
value={companyName}
onChange={(e) => setCompanyName(e.target.value)}
type="text"
placeholder="Company name"
required
className="block w-full shadow-sm focus:ring-primary focus:border-primary sm:text-sm border-gray-300 rounded-md dark:bg-gray-700 dark:border-gray-700 dark:placeholder-gray-300"
/>
</div>
<div className="grid grid-cols-6 gap-6">
<div className="col-span-6 sm:col-span-3">
<label htmlFor="first-name" className="sr-only">
First name
</label>
<input
value={firstName}
onChange={(e) => setFirstName(e.target.value)}
type="text"
placeholder="First name"
required
className="block w-full shadow-sm focus:ring-primary focus:border-primary sm:text-sm border-gray-300 rounded-md dark:bg-gray-700 dark:border-gray-700 dark:placeholder-gray-300"
/>
</div>
<div className="col-span-6 sm:col-span-3">
<label htmlFor="last-name" className="sr-only">
Last name
</label>
<input
value={lastName}
onChange={(e) => setLastName(e.target.value)}
type="text"
placeholder="Last name"
required
className="block w-full shadow-sm focus:ring-primary focus:border-primary sm:text-sm border-gray-300 rounded-md dark:bg-gray-700 dark:border-gray-700 dark:placeholder-gray-300"
/>
</div>
</div>
<div>
<label htmlFor="job-title" className="sr-only">
Job title
</label>
<input
value={jobTitle}
onChange={(e) => setJobTitle(e.target.value)}
type="text"
placeholder="Job title"
required
className="block w-full shadow-sm focus:ring-primary focus:border-primary sm:text-sm border-gray-300 rounded-md dark:bg-gray-700 dark:border-gray-700 dark:placeholder-gray-300"
/>
</div>
<div>
<label htmlFor="work-email" className="sr-only">
Work email
</label>
<input
value={email}
onChange={(e) => setEmail(e.target.value)}
type="email"
placeholder="Work email"
required
className="block w-full shadow-sm focus:ring-primary focus:border-primary sm:text-sm border-gray-300 rounded-md dark:bg-gray-700 dark:border-gray-700 dark:placeholder-gray-300"
/>
</div>
<div>
<label htmlFor="phone" className="sr-only">
Phone
</label>
<input
value={phone}
onChange={(e) => setPhone(e.target.value)}
type="text"
placeholder="Phone number"
required
className="block w-full shadow-sm focus:ring-primary focus:border-primary sm:text-sm border-gray-300 rounded-md dark:bg-gray-700 dark:border-gray-700 dark:placeholder-gray-300"
/>
</div>
<div>
<label htmlFor="password" className="sr-only">
Password
</label>
<input
value={password}
onChange={(e) => setPassword(e.target.value)}
type="password"
placeholder="Password"
required
className="block w-full shadow-sm focus:ring-primary focus:border-primary sm:text-sm border-gray-300 rounded-md dark:bg-gray-700 dark:border-gray-700 dark:placeholder-gray-300"
/>
</div>
<div>
<button
type="submit"
value="Register"
className="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-gray-900 hover:bg-btnhover focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-primary"
>
Create your account
</button>
</div>
<fieldset className="">
<legend className="sr-only">Notifications</legend>
<div className="relative flex items-start">
<div className="flex items-center h-5">
<input
id="comments"
aria-describedby="comments-description"
name="comments"
type="checkbox"
className="focus:ring-primary h-4 w-4 text-primary border-gray-300 rounded"
/>
</div>
<div className="ml-3 text-sm">
<label
htmlFor="comments"
className="font-medium text-gray-700 dark:text-white"
>
Don't be shy
</label>
<span
id="comments-description"
className="text-gray-500 dark:text-gray-300"
>
<span className="sr-only"></span> click here if
you want to speak to an expert from Tribeto to
help you get started.
</span>
</div>
</div>
</fieldset>
</form>
</div>
</div>
<div className="px-4 py-6 bg-gray-50 dark:bg-gray-700 border-t-2 border-gray-200 dark:border-gray-800 sm:px-10">
<p className="text-xs leading-5 text-gray-500 dark:text-white">
By signing up, you agree to our{" "}
<a
href="#"
className="font-medium text-gray-900 dark:text-primary hover:underline"
>
Terms
</a>
,{" "}
<a
href="#"
className="font-medium text-gray-900 dark:text-primary hover:underline"
>
Data Policy
</a>{" "}
and{" "}
<a
href="#"
className="font-medium text-gray-900 dark:text-primary hover:underline"
>
Cookies Policy
</a>
.
</p>
</div>
</div>
</div>
</div>
</div>
</main>
</div>
</div>
);
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
