Next.js Discord

Discord Forum

FormData can be seen when called on the onSubmit. However, passing this on the server action results

Unanswered
Jenn posted this in #help-forum
Open in Discord
Posted in SO as well: https://stackoverflow.com/questions/77383164/formdata-can-be-seen-when-called-on-the-onsubmit-however-passing-this-on-the-s

Codes were quite too long so here's the explanation:
I have a form where I can already see the formData when being submitted. Data shows in the console. However, when I call the server function call to receive the formData, this would result to null.

  async function onSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault(); // Prevent the default form submission behavior

    console.log(formData,"formData under waterStation file form")
   
    const res = await addWaterStation(new FormData(event.currentTarget))
    setMessage(res.message);
  }


Then on the server actions:
export default async function addWaterStation(formData: FormData): Promise<{ message: string }> {
    console.log(formData, "form data under water station.ts")
    const supabase =createServerComponentClient({cookies})
    const {data: {user}} = await supabase.auth.getUser();
    const formDataAddress = `${formData.get('buildingNumber')}, ${formData.get('street')}, ${formData.get('zone')}`

    try{
        const station_name = formData.get('name')
        ..other data
        
        const {data, error} = await supabase.from('water_refilling_station')
            .insert({
                created_at,
                ..other data
            }).select()
        
        if(error){
            return {message: `${error.message}  - unable to save`}
        } 

        revalidatePath('/water_station')
        return{message: 'Succesfully Added the Water Station Information'}
    }catch(e){
        return {message: "Failed to submit the form."}
    }

}

11 Replies

server action require the function pass as the action props on the form. not onSubmit
@Ray https://github.com/vercel/next.js/tree/canary/examples/next-forms check the example here
I followed this now, however, the formData is still null. `
interface FormData {
name: string;
buildingNumber: string;
street: string;
zone: string;
landmark: string;
barangay: string;
delivery_mode: string;
contact_no: number | null;
tel_no: number | null;
remarks: string | null;
}

const initialState = {
message: null,
}

function SubmitButton() {
const { pending } = useFormStatus()

return (
<button type="submit" aria-disabled={pending}>
Add
</button>
)
}

export default function WaterStationProfileForm() {
const [state, formAction] = useFormState(addWaterStation, initialState)
const [message, setMessage] = useState<string>('');
const [formData, setFormData] = useState<FormData>({
name: "",
buildingNumber: "",
street: "",
zone: "",
landmark: "",
barangay: "",
delivery_mode: "",
contact_no: null,
tel_no: null,
remarks: null,
});

// async function onSubmit(event: FormEvent<HTMLFormElement>) {
// event.preventDefault(); // Prevent the default form submission behavior

// console.log(formData,"formData under waterStation file form")

// // const res = await addWaterStation(formData);
// // setMessage(res.message);
// }

return (
<div className="container mx-auto p-4">
<form action={formAction}>
<MyInput
label="Water Station Name"
name="name"
value={formData.name}
onChange={(name, value) => setFormData({ ...formData, [name]: value })}
required={true}
type="text"
/>
And the on the ts
'use server'
export default async function addWaterStation(prevState: any, formData: FormData): Promise<{ message: string }> {    const supabase =createServerComponentClient({cookies})
    const {data: {user}} = await supabase.auth.getUser();
    const formDataAddress = `${formData.get('buildingNumber')}, ${formData.get('street')}, ${formData.get('zone')}`
    console.log(formData.get("name"), "station name")

    try{
        const station_name = formData.get('name')
         ...

        //FormData values are of String data type
        const contact_no_string = formData.get("contact_no") as string
        const tel_no_string = formData.get("tel_no") as string

        //parsing contact no and tel_no to null if the values are blank
        const contact_no = contact_no_string ? parseInt(contact_no_string) : null;
        const tel_no = tel_no_string ? parseInt(tel_no_string) : null;


        const remarks = formData.get("remarks")
        const created_at = new Date()
        
        const {data, error} = await supabase.from('water_refilling_station')
            .insert({
                created_at,
                ...
            }).select()
        
        if(error){
            // return {message: `${error.message}  - unable to save`}
            console.log(error)
        } 

        revalidatePath('/water_station')
        return{message: 'Succesfully Added the Water Station Information'}
    }catch(e){
        return {message: "Failed to submit the form."}
    }

}
try with normal html input
<input type='text' name='name' required />
@Ray try with normal html input `<input type='text' name='name' required />`
I have already fixed it. However, the message does not show like: message: 'Succesfully Added the Water Station Information' and any error messages are not shown as well. But, I can succesffuly submit it already
'use server'
export default async function addWaterStation(prevState: any, formData: FormData): Promise<{ message: string }> {    const supabase =createServerComponentClient({cookies})
    const {data: {user}} = await supabase.auth.getUser();
    const formDataAddress = `${formData.get('buildingNumber')}, ${formData.get('street')}, ${formData.get('zone')}`
    console.log(formData, "formData")

    try{
        const station_name = formData.get('name')
        const user_id = user?.id
        const address = formDataAddress
        const landmark = formData.get('landmark')
        const barangay = formData.get('barangay')
        const delivery_mode = formData.get("delivery_mode")

        //FormData values are of String data type
        const contact_no_string = formData.get("contact_no") as string
        const tel_no_string = formData.get("tel_no") as string

        //parsing contact no and tel_no to null if the values are blank
        const contact_no = contact_no_string ? parseInt(contact_no_string) : null;
        const tel_no = tel_no_string ? parseInt(tel_no_string) : null;


        const remarks = formData.get("remarks")
        const created_at = new Date()
        
        const {data, error} = await supabase.from('water_refilling_station')
            .insert({
                station_name,
                created_at,
                user_id,
                landmark,
                address,
                barangay,
                remarks,
                contact_no,
                tel_no,
                delivery_mode,
            }).select()
        
        if(error){
            return {message: `${error.message}  - unable to save`}
        } 

        revalidatePath('/water_station')
        return { message: `Succesfully added the data` }
    }catch(e){
        return {message: "Failed to submit the form."}
    }

}
Then calling it here