I'm using react-hook-form
with yup
for my form validation and want some fields to be optional (null).
Following their documentation, I'm using nullable()
and optional()
but it is still getting validated:
export const updateAddressSchema = yup.object({
address: yup
.string()
.nullable()
.optional()
.min(5, "Address must be more than 5 characters long")
.max(255, "Address must be less than 255 characters long"),
city: yup
.string()
.nullable()
.optional()
.max(32, "City name must be less than 32 characters long"),
postal_code: yup
.string()
.nullable()
.optional()
.length(10, "Postal code must be 10 characters long"),
phone: yup
.string()
.nullable()
.optional()
.min(10, "Phone number must be more than 10 characters long")
.max(20, "Phone number must be less than 20 characters long"),
});
Is there any right way to do this?
CodePudding user response:
You need to use .when
for conditional validation like this below. I have added only for address
and city
only, you can add for other like this.
export const updateAddressSchema = yup.object().shape({
address: yup.string().when("address", (val, schema) => {
if (val) {
if(val.length > 0) { //if address exist then apply min max else not
return yup.string().min(5, "min 5").max(255, "max 255").required("Required");
} else {
return yup.string().notRequired();
}
} else {
return yup.string().notRequired();
}
}),
city: yup.string().when("city", (val, schema) => {
if (val) {
if(val.length > 0) {
return yup.string().max(32, "max 32").required("Required");
}
else {
return yup.string().notRequired();
}
} else {
return yup.string().notRequired();
}
}),
}, [
["address", "address"],
["city", "city"],
] //cyclic dependency
);
Also, you need to add Cyclic dependency
CodePudding user response:
Thanks a lot to @Usama for their answer and solution!
I experienced another problem when using their solution. My back-end API disregards null values and returns the previous value if null values are submitted. The problem was that on initial render the text field's value was null but after selecting and typing and then deleting the typed letters to get it empty again (without submitting), its value would change to an empty string and so my API would throw an error and wouldn't update the user info.
The way I managed to fix it was to use yup
's .transform()
method to transform the type from empty string to null if the text field wasn't filled:
export const updateAddressSchema = yup.object().shape(
{
address: yup.string().when("address", (value) => {
if (value) {
return yup
.string()
.min(5, "Address must be more than 5 characters long")
.max(255, "Address must be less than 255 characters long");
} else {
return yup
.string()
.transform((value, originalValue) => {
// Convert empty values to null
if (!value) {
return null;
}
return originalValue;
})
.nullable()
.optional();
}
}),
......................
},
[
["address", "address"],
......................,
]
);
I really hope this helps someone.