Z
Zod8mo ago
adxvcasas

adxvcasas - Hello everyone, How can I make the ...

Hello everyone, How can I make the dryRunDate ,dryRunStart and dryRunEnd dynamic? so I have a type who have a value of yes and no. Is it possible to make dryRunDate ,dryRunStart and dryRunEnd required if the user select yes from type? this is my zod
const FormSchema = z.object({
type: z.enum(["yes", "no"], {
required_error: "You need to select a notification type.",
}),
dryRunDate: z.string().optional(),
dryRunStart: z.string().optional(),
dryRunEnd: z.string().optional(),
})
const FormSchema = z.object({
type: z.enum(["yes", "no"], {
required_error: "You need to select a notification type.",
}),
dryRunDate: z.string().optional(),
dryRunStart: z.string().optional(),
dryRunEnd: z.string().optional(),
})
8 Replies
Svish
Svish8mo ago
You need to use a union (a discriminated one if possible). Alternatively you need to use refine/superRefine and do the check manually there
adxvcasas
adxvcasasOP8mo ago
Hello @Svish , I tried doing it like this.
const FormSchema = z.object({
type: z.enum(["yes", "no"], {
required_error: "You need to select a notification type.",
}),
dryRunDate: z.string().optional(),
dryRunStart: z.string().optional(),
dryRunEnd: z.string().optional(),
}).refine(data => {
if (data.type === 'yes') {
return {
dryRunDate: data.dryRunDate || 'Required field',
dryRunStart: data.dryRunStart || 'Required field',
dryRunEnd: data.dryRunEnd || 'Required field',
};
}
return true;
};
const FormSchema = z.object({
type: z.enum(["yes", "no"], {
required_error: "You need to select a notification type.",
}),
dryRunDate: z.string().optional(),
dryRunStart: z.string().optional(),
dryRunEnd: z.string().optional(),
}).refine(data => {
if (data.type === 'yes') {
return {
dryRunDate: data.dryRunDate || 'Required field',
dryRunStart: data.dryRunStart || 'Required field',
dryRunEnd: data.dryRunEnd || 'Required field',
};
}
return true;
};
I don't know if i'm doing it correctly or not, Thanks
Svish
Svish8mo ago
You're sort of on the right track if you want to use refine, but that's not how refine works. It should just return true or false. To set the error message, you there's a second parameter of refine with options. In this case, since you're checking multiple fields, you should probably use superRefine or transform instead. Both get a ctx parameter where you can check things and call ctx.addIssue for whatever you need Check the documentation for those functions on https://zod.dev
adxvcasas
adxvcasasOP8mo ago
what if I change the type.enum to true or false? is this still applicable? Thank you
Svish
Svish8mo ago
If I were you I would try the discriminated union Then you'd use type as the discriminator, and z.literal(true) and z.literal(false) for the two "branches" in the union
adxvcasas
adxvcasasOP8mo ago
Hello, I tried experemnting it, is this thing worth?
const FormSchema = z.object({
type: z.enum(["yes", "no"], {
required_error: "You need to select a notification type.",
}),
dryRunDate: z.string().optional(),
}).refine(data => {
if (data.type === "yes" && !data.dryRunDate) {
throw new Error("Dry run date is required when type is 'yes'.");
}
return true;
});
const FormSchema = z.object({
type: z.enum(["yes", "no"], {
required_error: "You need to select a notification type.",
}),
dryRunDate: z.string().optional(),
}).refine(data => {
if (data.type === "yes" && !data.dryRunDate) {
throw new Error("Dry run date is required when type is 'yes'.");
}
return true;
});
Svish
Svish8mo ago
Have you read the docs? https://zod.dev/?id=refine What you're doing there is not correct, no. Look at the examples in the documentation
adxvcasas
adxvcasasOP8mo ago
Hello, Svish, I did this thing,
const FormSchema = z.object({
type: z.enum(["yes", "no"], {
required_error: "You need to select a notification type.",
}),
dryRunDate: z.string().optional(),
}).superRefine(({type,dryRunDate}, ctx ) => {
if(type === 'yes' && dryRunDate === ''){
ctx.addIssue({
code: 'custom',
message: "Please fill up the field",
path: ['dryRunDate']
})
}
})
const FormSchema = z.object({
type: z.enum(["yes", "no"], {
required_error: "You need to select a notification type.",
}),
dryRunDate: z.string().optional(),
}).superRefine(({type,dryRunDate}, ctx ) => {
if(type === 'yes' && dryRunDate === ''){
ctx.addIssue({
code: 'custom',
message: "Please fill up the field",
path: ['dryRunDate']
})
}
})
It works on 1 pair only but if I add the other two, the warning didn't show.
const FormSchema = z.object({
type: z.enum(["yes", "no"], {
required_error: "You need to select a notification type.",
}),
dryRunDate: z.string().optional(),
dryRunStart: z.string().optional(),
dryRunEnd: z.string().optional(),
}).superRefine(({type,dryRunDate, dryRunStart, dryRunEnd}, ctx ) => {
if(type === 'yes' && dryRunDate === '' && dryRunStart === '' && dryRunEnd === ''){
ctx.addIssue({
code: 'custom',
message: "Please fill up the field",
path: ['dryRunDate', 'dryRunStart', 'dryRunEnd']
})
}
})
const FormSchema = z.object({
type: z.enum(["yes", "no"], {
required_error: "You need to select a notification type.",
}),
dryRunDate: z.string().optional(),
dryRunStart: z.string().optional(),
dryRunEnd: z.string().optional(),
}).superRefine(({type,dryRunDate, dryRunStart, dryRunEnd}, ctx ) => {
if(type === 'yes' && dryRunDate === '' && dryRunStart === '' && dryRunEnd === ''){
ctx.addIssue({
code: 'custom',
message: "Please fill up the field",
path: ['dryRunDate', 'dryRunStart', 'dryRunEnd']
})
}
})
const FormSchema = z.object({
type: z.enum(["yes", "no"], {
required_error: "You need to select a notification type.",
}),
dryRunDate: z.string().optional(),
dryRunStart: z.string().optional(),
dryRunEnd: z.string().optional(),
}).superRefine(({ type, dryRunDate, dryRunStart, dryRunEnd }, ctx) => {
if (type === 'yes') {
if (!dryRunDate) {
ctx.addIssue({
code: 'custom',
message: 'dryRunDate is required to fill up if you choose yes.',
path: ['dryRunDate']
})
}
if (!dryRunStart) {
ctx.addIssue({
code: 'custom',
message: 'dryRunStart is required to fill up if you choose yes.',
path: ['dryRunStart']
})
}
if (!dryRunEnd) {
ctx.addIssue({
code: 'custom',
message: 'dryRunEnd is required to fill up if you choose yes.',
path: ['dryRunEnd']
})
}
}
});
const FormSchema = z.object({
type: z.enum(["yes", "no"], {
required_error: "You need to select a notification type.",
}),
dryRunDate: z.string().optional(),
dryRunStart: z.string().optional(),
dryRunEnd: z.string().optional(),
}).superRefine(({ type, dryRunDate, dryRunStart, dryRunEnd }, ctx) => {
if (type === 'yes') {
if (!dryRunDate) {
ctx.addIssue({
code: 'custom',
message: 'dryRunDate is required to fill up if you choose yes.',
path: ['dryRunDate']
})
}
if (!dryRunStart) {
ctx.addIssue({
code: 'custom',
message: 'dryRunStart is required to fill up if you choose yes.',
path: ['dryRunStart']
})
}
if (!dryRunEnd) {
ctx.addIssue({
code: 'custom',
message: 'dryRunEnd is required to fill up if you choose yes.',
path: ['dryRunEnd']
})
}
}
});
This one works fine, Thank you
Want results from more Discord servers?
Add your server