"Next JS 14 Error: TypeError: e._formData.get is not a function using Appwrite Backend"

494 views Asked by At

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,
    });
  }
}

Error

I would appreciate any guidance on resolving this error.

1

There are 1 answers

0
Saabir Mohamed On

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

 export function resetRequest() {


    const validateReset = async (formData: FormData) => {
        'use server';
        var possibleClientEmail = formData.get('email') as String;
        if (possibleClientEmail !== null) {
            // find the user (not in the database)
            const areTheyLying = database.listDocuments(db, usersCollection,
                [
                    Query.isNotNull("email"),
                    Query.equal("email", [possibleClientEmail.toString()])

                ],
            );

            areTheyLying.then(async function (okIBelieveYou: Models.DocumentList<Models.Document>) {
                console.log(okIBelieveYou); // Success
                // shame he/she is not lying ...go send him the recovery email
                var truthFullPerson = '';
                okIBelieveYou.documents.forEach((doc) => {
                    truthFullPerson = doc.$id;
                });
                const okFineHereYouGoIPromise = account.createRecovery(possibleClientEmail!.toString(), 'https://yourwebsite/recovery');

                okFineHereYouGoIPromise.then(function (okTakeThisDontShowAnyone: Models.Token) {
                    console.log(okTakeThisDontShowAnyone.secret); // Success
                    console.log(okTakeThisDontShowAnyone.userId); // Success
                    // direct them to a place of happiness
                    redirect(`/email_sent_success`) // Navigate to the new post page

                }, function (error) {
                    console.log(error); // Failure
                });
            }, function (error) {
                console.log(error); // Failure
            });
        };
        return;
    }

}

// note when i put as String...no error ...but no redirect