Zod validation on forms vs fields #1586
-
I was following along with https://www.youtube.com/watch?v=Pys2ExswZT0 and https://www.youtube.com/watch?v=HSboMHfPuZA from Balastrong's stuff when I found some interesting behavior.
edit:The implementation of my error display was rendering an undefined value from different returned error bodies fix://....
validators= {{
onChangeListenTo: ["password"],
onChange: ({ value, fieldApi }) => {
- value !== fieldApi.form.getFieldValue("password") &&
- "Passwords do not match";},
+ if (value !== fieldApi.form.getFieldValue("password")) {
+ return { message: "Passwords do not match" };
}} ex. function LoginPage() {
const form = useAppForm({
defaultValues: {
password: "",
confirmPassword: "",
},
validators: {
onBlur: z
.object({
password: z
.string()
.min(8, { message: "Must be 8 characters or more" })
.max(32, { message: "Must be 32 characters or less" }),
confirmPassword: z.string(),
})
// .......
return (
<>
<form>
// .....
<form.Field
name="confirmPassword"
validators={{
onChangeListenTo: ["password"],
onChange: ({ value, fieldApi }) => {
value !== fieldApi.form.getFieldValue("password") &&
"Passwords do not match";
},
}}
// what to render
children={(field) => (
<>
<input
type="password"
name={field.name}
placeholder={"Confirm password"}
value={field.state.value}
onChange={(e) => field.handleChange(e.target.value)}
onBlur={(e) => field.handleBlur?.()}
/>
{/* show field errors after input */}
{field.state.meta.isTouched && !field.state.meta.isValid && (
<div className="text-red-500 font-bold text-sm">
{field.state.meta.errors[0]?.message as string}
</div>
)}
</>
)}
/>
</form>
</>
)
} this custom field validation on confirmPassword
gets ignored in favor of the zod form schema for that field =================================== We can use only inline zod for fields (and do a check for field errors on form state onSubmit/onBlur) or use Zod to add the similar confirmPassword behavior as shown in the tutorial. const LoginSchema = z
.object(
password: z
.string()
.min(8, { message: "Must be 8 characters or more" })
.max(32, { message: "Must be 32 characters or less" }),
confirmPassword: z.string(),
})
.superRefine(({ password, confirmPassword }, ctx) => {
if (password !== confirmPassword) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Passwords do not match",
path: ["confirmPassword"],
});
}
}) |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
Standard schema issues are objects with a Field validator errors (should) take precedence over form validator errors, and I'm able to recreate it on a stackblitz example. |
Beta Was this translation helpful? Give feedback.
Standard schema issues are objects with a
message
property, but your field validator returns a string for the error. Your error may resolve to undefined (<string>.message
) and won't be rendered. Could you double check the typing?Field validator errors (should) take precedence over form validator errors, and I'm able to recreate it on a stackblitz example.
https://stackblitz.com/edit/tanstack-form-jff7pyyu?file=src%2Findex.tsx