FormData can be seen when called on the onSubmit. However, passing this on the server action results
Unanswered
Jenn posted this in #help-forum
JennOP
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.
Then on the server actions:
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
https://github.com/vercel/next.js/tree/canary/examples/next-forms
check the example here
check the example here
@Ray https://github.com/vercel/next.js/tree/canary/examples/next-forms
check the example here
JennOP
I followed this now, however, the
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"
/>
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 />`
JennOP
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
JennOP
I have also posted it here: https://stackoverflow.com/questions/77386356/return-messages-in-server-actions-are-not-shown-or-displayed