I am using useForm react hook + zod for validation schemas.
From the formState all values returned are as expected, but the “errors” object. I am trying to set hasError of an input and no matter the value “errors” is always empty.
<code> // Initialize react-hook-form with default values
formState: { errors, touchedFields, isValid, isDirty },
defaultValues: initialValues,
resolver: zodResolver(OpeningHoursBodySchema),
<code> // Initialize react-hook-form with default values
const {
register,
watch,
reset,
getValues,
setValue,
formState: { errors, touchedFields, isValid, isDirty },
} = useForm({
defaultValues: initialValues,
resolver: zodResolver(OpeningHoursBodySchema),
});
</code>
// Initialize react-hook-form with default values
const {
register,
watch,
reset,
getValues,
setValue,
formState: { errors, touchedFields, isValid, isDirty },
} = useForm({
defaultValues: initialValues,
resolver: zodResolver(OpeningHoursBodySchema),
});
<code><Box mr={3.75} width="auto">
hasError={touchedFields.address?.street && !!errors.address?.street}
<Typography display="block" variant="mainBold">
<Typography color="red.main" component="sup">
{...register("address.street")}
placeholder={ts("general.street")}
<code><Box mr={3.75} width="auto">
<InputField
border
hasError={touchedFields.address?.street && !!errors.address?.street}
label={
<Typography display="block" variant="mainBold">
{ts("general.street")}
<Typography color="red.main" component="sup">
*
</Typography>
</Typography>
}
{...register("address.street")}
smallSize
placeholder={ts("general.street")}
/>
</Box>;
</code>
<Box mr={3.75} width="auto">
<InputField
border
hasError={touchedFields.address?.street && !!errors.address?.street}
label={
<Typography display="block" variant="mainBold">
{ts("general.street")}
<Typography color="red.main" component="sup">
*
</Typography>
</Typography>
}
{...register("address.street")}
smallSize
placeholder={ts("general.street")}
/>
</Box>;
Those are the schemas that I use:
<code>export const ModuleAddressSchema = z.object({
street: z.string().min(1, { message: REQUIRED }),
houseNumber: z.string().min(1, { message: REQUIRED }),
city: z.string().min(1, { message: REQUIRED }),
zip: z.string().min(1, { message: REQUIRED }),
export const OpeningHoursSchema = z.object({
startDate: z.string().min(1, { message: "Date should not be empty" }),
endDate: z.string().min(1, { message: "Date should not be empty" }),
timezone: z.string().optional(),
weeklyOpeningTimes: WeeklyOpeningTimesSchema,
address: ModuleAddressSchema.refine(
return Object.values(moduleAddress).every((field) => field.length > 0);
{ message: "This field is required" }
<code>export const ModuleAddressSchema = z.object({
street: z.string().min(1, { message: REQUIRED }),
houseNumber: z.string().min(1, { message: REQUIRED }),
city: z.string().min(1, { message: REQUIRED }),
zip: z.string().min(1, { message: REQUIRED }),
});
export const OpeningHoursSchema = z.object({
eventId: z.number(),
startDate: z.string().min(1, { message: "Date should not be empty" }),
endDate: z.string().min(1, { message: "Date should not be empty" }),
timezone: z.string().optional(),
weeklyOpeningTimes: WeeklyOpeningTimesSchema,
address: ModuleAddressSchema.refine(
(moduleAddress) => {
return Object.values(moduleAddress).every((field) => field.length > 0);
},
{ message: "This field is required" }
),
});
</code>
export const ModuleAddressSchema = z.object({
street: z.string().min(1, { message: REQUIRED }),
houseNumber: z.string().min(1, { message: REQUIRED }),
city: z.string().min(1, { message: REQUIRED }),
zip: z.string().min(1, { message: REQUIRED }),
});
export const OpeningHoursSchema = z.object({
eventId: z.number(),
startDate: z.string().min(1, { message: "Date should not be empty" }),
endDate: z.string().min(1, { message: "Date should not be empty" }),
timezone: z.string().optional(),
weeklyOpeningTimes: WeeklyOpeningTimesSchema,
address: ModuleAddressSchema.refine(
(moduleAddress) => {
return Object.values(moduleAddress).every((field) => field.length > 0);
},
{ message: "This field is required" }
),
});
I added the .refine()
, because the trying with .min()
didn’t work and I thought the issue may be the nested object schema.
Also used this from the useForm documentation to debug my resolver and it’s showing the proper errors with messages from the zod .refine()
method
<code>resolver: async (data, context, options) => {
await zodResolver(OpeningHoursBodySchema)(data, context, options)
return zodResolver(OpeningHoursBodySchema)(data, context, options)
<code>resolver: async (data, context, options) => {
console.log(
"validation result",
await zodResolver(OpeningHoursBodySchema)(data, context, options)
)
return zodResolver(OpeningHoursBodySchema)(data, context, options)
}
</code>
resolver: async (data, context, options) => {
console.log(
"validation result",
await zodResolver(OpeningHoursBodySchema)(data, context, options)
)
return zodResolver(OpeningHoursBodySchema)(data, context, options)
}