If you want to validate an array of objects from this Schema
const fieldsOfEng = [
{
id: "ELECTRICAL",
name: "Electrical",
experience: 1,
},
{
id: "MECHANICAL",
name: "Mechanical",
experience: undefined,
},
];
I'd do it like this
const userInfoSchema = z.object({
id: z.string(),
name: z.string(),
experience: z.number().optional()
})
// Now add this object into an array
const usersInfoSchema = z.array(userInfoSchema)
Answer from Ark on Stack OverflowIf you want to validate an array of objects from this Schema
const fieldsOfEng = [
{
id: "ELECTRICAL",
name: "Electrical",
experience: 1,
},
{
id: "MECHANICAL",
name: "Mechanical",
experience: undefined,
},
];
I'd do it like this
const userInfoSchema = z.object({
id: z.string(),
name: z.string(),
experience: z.number().optional()
})
// Now add this object into an array
const usersInfoSchema = z.array(userInfoSchema)
This answer is an update on my progress so far. I closer to getting my schema validation working correctly but for some reason it is not submitting. I could solve this faster if I could get react-hook form's errors to output correctly but since I'm using template literals when I'm registering the inputs, the error is just outputting nothing. I DO know there is an error though because my truthy error outputs the "professions:" string that I added in the p-tag.
Data for checkboxes in form (this is the data I'm validating via zod):
const fieldsOfEng = [
{
id: "ELECTRICAL",
name: "Electrical",
experience: undefined,
},
{
id: "MECHANICAL",
name: "Mechanical",
experience: undefined,
},
Schema for validation: I'm checking that the name they select is included in my fieldsOfEng array and making sure the experience is greater than 1.
const userInfoSchema = object({
professions: z
.object({
name: z
.string()
.refine((name) =>
fieldsOfEng.map((field) => field.name).includes(name)
),
experience: z.number().refine((experience) => experience > 1),
})
.array(),
});
React hook form:
type userInfoType = z.infer<typeof userInfoSchema>;
const {
register,
watch,
handleSubmit,
formState: { errors, isSubmitting },
} = useForm<userInfoType>({
resolver: zodResolver(userInfoSchema),
});
Form: Notice I am using template literals for registering each input. It took me forever to figure this out. So far this is the only way I've been able to get the data to output correctly (via react-hook-form's 'watch' method).
<fieldset>
<legend>Practicing fields of engineering</legend>
{fieldsOfEng.map((field, i) => {
return (
<div key={field.id}>
<div>
<input
{...register(`professions.${i}.name`)} <--REGISTERED HERE
value={field.name}
type="checkbox"
/>
<div>
<input
{...register(`professions.${i}.experience`)} <--REGISTERED HERE
type="number"
value={field.experience}
placeholder="Yrs Experience"
/>
</div>
</div>
<div>
{errors.professions && (
<p>
professions:
{errors.professions.message}
</p>
)}
</div>
</div>
);
})}
</fieldset>