How can I validate a field conditionally based on the value of another field in a zod form schema, ensuring all validations run simultaneously? #3268
-
I need to validate one field in a form based on the value of another field. Both fields are part of a form, where there are other mandatory fields. Eg: Form has a type: I'm already aware of .refine() and .superRefine() and I have tried using both of them. The problem faced when using those 2 methods are that, the dependant validations run only after mandatory validation checks have passed. Is there a way to run all the checks at the same time ? How I tried to do the validation: z.object({ The problem I noticed with this solution is that, organisationName field's validation is visible only after i fill both name & email fields. The scenario is pretty common for forms. I need all my validations to run together. Requesting help and guidance. |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 2 replies
-
Is this what you are looking for? const typeEnum = z.enum( [ 'Private', 'Business' ] )
const schema = z.discriminatedUnion( 'type', [
z.object( {
name: z.string(),
email: z.string(),
type: typeEnum.extract( [ 'Private' ] ),
organisationName: z.string().optional(),
} ),
z.object( {
name: z.string(),
email: z.string(),
type: typeEnum.extract( [ 'Business' ] ),
organisationName: z.string(),
} ),
] )
type Data = z.infer<typeof schema>
// type Data = {
// type: "Private"
// name: string
// email: string
// organisationName?: string | undefined
// } | {
// type: "Business"
// name: string
// email: string
// organisationName: string
// } If you found my answer satisfactory, please consider supporting me. Even a small amount is greatly appreciated. Thanks friend! 🙏 |
Beta Was this translation helpful? Give feedback.
-
Maybe you just looking for this version? const FormSchema = z.discriminatedUnion("bulk", [
z.object({
language: z.string().min(2, {
message: "Language must be at least 2 characters.",
}),
key: z.string().min(5, {
message: "Key must be at least 2 characters.",
}),
value: z.string().min(5, {
message: "Key must be at least 5 characters.",
}),
actor: z.string(),
projectId: z.number(),
bulk: z.literal(false),
}),
z.object({
actor: z.string(),
projectId: z.number(),
resume: z.instanceof(File).refine((file) => file.size < 7000000, {
message: "Your resume must be less than 7MB.",
}),
bulk: z.literal(true),
}),
]); |
Beta Was this translation helpful? Give feedback.
please explain how my answer didn't accomplish what you are asking for.