Return messages in server actions are not shown or displayed
Unanswered
Jenn posted this in #help-forum
Original message was deleted.
6 Replies
Form Submission
'use client'
interface FormData {
name: string;
...the rest of the data
}
const initialState = {
message: null,
}
function SubmitButton() {
const { pending } = useFormStatus()
return (
<button type="submit" aria-disabled={pending}>
Submit
</button>
)
}
export default function WaterStationProfileForm() {
const [state, formAction] = useFormState(addWaterStation, initialState)
const [formValue, setFormValue] = useState<FormData>({
...rest of the data
});
return (
<div className="container mx-auto p-4">
<p aria-live="polite" className="sr-only" role="status">
{state?.message}
</p>
<form action={formAction}>
<MyInput
id="name"
label="Water Station Name"
name="name"
value={formValue.name}
onChange={(event) => setFormValue({ ...formValue, [event.target.name]: event.target.value })}
required
type="text"
errors={state.errors}
/>
... the rest of the input fields
<SubmitButton />
</form>
</div>
);
}Server action
'use server'
import { createServerComponentClient } from "@supabase/auth-helpers-nextjs"
import { revalidatePath } from "next/cache";
import { cookies } from "next/headers"
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')
...rest of the data
const {data, error} = await supabase.from('water_refilling_station')
.insert({
station_name,
...rest of the data
}).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."}
}
}Reusable component for the input fields:
interface MyInputProps {
label: string;
name: string;
id: string;
value: string | number;
onChange: (event: any) => void;
errors: any;
// onChange: (name: string, value: string | number | null) => void;
required?: boolean;
type?: 'text' | 'number';
}
const MyInput: React.FC<MyInputProps> = ({
label,
name,
id,
value,
onChange,
errors,
required = false,
type = 'text',
}: MyInputProps) => {
//extract errors
let error;
if(errors && errors[name]) {
error = errors[name];
}
return (
<div className="mb-4">
<label className="block text-lg font-semibold text-blue-700 mb-2">{label}</label>
<input
type={type}
id={id}
name={name}
required={required}
value={value}
onChange={onChange}
/>
{error && <p className="text-red-500 text-lg italic mt-2">{error}</p>}
</div>
);
};
export default MyInput;