I'm working with Next JS 14 and using Appwrite as my backend. I've run into an issue where submitting a form results in a TypeError: e._formData.get is not a function
. This error seems to occur after the first form submission, whether it's successful or not. Refreshing the page does not resolve the issue, and the error persists on subsequent submissions:
SignUpPage.tsx:
import SignupForm from "./components/signupForm";
import axios from "axios";
const onSubmit = async (name: string, email: string, password: string) => {
"use server";
console.log("SERVER name", name);
console.log("SERVER email", email);
console.log("SERVER password", password);
const response = await fetch("http://localhost:3000/api/auth/signup", {
method: "POST",
headers: {
"Content-Type": "application/JSON",
},
body: JSON.stringify({
name,
email,
password,
}),
});
console.log("response", JSON.parse(JSON.stringify(response)));
if (response.status === 200) {
return JSON.parse(JSON.stringify(response));
}
return {
status: response.status,
};
};
const SignUpPage = () => {
return (
<div className="min-h-screen flex items-center justify-center bg-gray-100 px-6">
<div className="w-full max-w-md">
<h1 className="mb-6 text-center text-3xl font-bold text-gray-900">
Registro
</h1>
<SignupForm onSubmit={onSubmit} />
</div>
</div>
);
};
export default SignUpPage;
signupForm.tsx:
"use client";
import { FormEvent } from "react";
import { useState } from "react";
const SignupForm = ({
onSubmit,
}: {
onSubmit: (name: string, email: string, password: string) => void;
}) => {
const [errorMsg, setErrorMsg] = useState('');
const [isLoading, setIsLoading] = useState(false);
const handleSubmit = async (event: FormEvent<HTMLFormElement>) => {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const email = formData.get("email") as string;
const name = formData.get("name") as string;
const password = formData.get("password") as string;
setIsLoading(true);
console.log("name", name);
console.log("email", email);
console.log("pass", password);
try {
const response = await onSubmit(name, email, password);
console.log("response", response);
} catch (error:any) {
console.log('ERROR: ', error?.message);
setErrorMsg(error?.message || 'ERROR');
}finally{
setIsLoading(false);
}
};
return (
<form onSubmit={handleSubmit} className="bg-white shadow-lg rounded-lg p-8">
<div className="mb-4">
<label
className="block text-gray-700 text-sm font-semibold mb-2"
htmlFor="name"
>
Nombre
</label>
<input
type="text"
name="name"
id="name"
placeholder="Tu nombre completo"
required
className="shadow-sm bg-gray-50 border border-gray-300 rounded-md py-2 px-3 block w-full outline-none focus:ring-indigo-500 focus:border-indigo-500 text-gray-700"
/>
</div>
<div className="mb-4">
<label
className="block text-gray-700 text-sm font-semibold mb-2"
htmlFor="email"
>
Email
</label>
<input
type="email"
name="email"
id="email"
placeholder="[email protected]"
required
className="shadow-sm bg-gray-50 border border-gray-300 rounded-md py-2 px-3 block w-full outline-none focus:ring-indigo-500 focus:border-indigo-500 text-gray-700"
/>
</div>
<div className="mb-6">
<label
className="block text-gray-700 text-sm font-semibold mb-2"
htmlFor="password"
>
Contraseña
</label>
<input
type="password"
name="password"
id="password"
placeholder="••••••••"
required
className="shadow-sm bg-gray-50 border border-gray-300 rounded-md py-2 px-3 block w-full outline-none focus:ring-indigo-500 focus:border-indigo-500 text-gray-700"
/>
</div>
{errorMsg && <p className="error">{errorMsg}</p>}
<div className="mb-4">
<button
disabled={isLoading}
type="submit"
className="w-full py-2 px-4 bg-indigo-600 hover:bg-indigo-700 rounded-md shadow-sm text-white text-sm font-medium focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2"
>
{isLoading ? 'Cargando...' : 'Registrar'}
</button>
</div>
</form>
);
};
export default SignupForm;
route.tsx:
import { Account, Client, ID } from "appwrite";
import { revalidatePath } from "next/cache";
import { NextRequest, NextResponse } from "next/server";
type Payload = {
email: string;
name: string;
password: string;
};
export async function GET(request: NextRequest) {
return NextResponse.json({ messsage: "Hello World" });
}
export async function POST(request: NextRequest) {
const body: Payload = await request.json();
const { email, name, password } = body;
try {
const client = new Client()
.setEndpoint(`${process.env.APPWRITE_ENDPOINT}`) // Your API Endpoint
.setProject(`${process.env.APPWRITE_PROJECT_ID}`);
const account = new Account(client);
console.log("account", JSON.stringify(account));
const result = await account.create(ID.unique(), email, password, name);
const path = request.nextUrl.searchParams.get('path') || '/';
revalidatePath(path);
return NextResponse.json({
status: 201,
message: "Account Created",
data: JSON.stringify(result),
error: null,
});
} catch (error: any) {
console.error("Error:", error);
if (error.code === 409) {
return NextResponse.json({
status: 409,
message: "A user with the same id, email, or phone already exists.",
error: error.response,
});
}
return NextResponse.json({
status: error.code || 500,
message: "An error occurred",
error: error.response,
});
}
}
I would appreciate any guidance on resolving this error.
I have the same issue, using appwrite as well. with password recovery though; i think the result from this line ...my code is pasted here
var possibleClientEmail = formData.get('email') as String;
// i cast it ..then no error but no redirect after success
// note when i put as String...no error ...but no redirect