So while learning, forms i found this package - yup for validating. But i am getting a problem
So i will explain the problem statement and what i have tried so far.
So the use case is i have a select field, which has two options, Resident and Non-Resident, so based on the selection i have different fields which i render
- Resident : first_name, last_name
- Non-Resident: passport_number, country, state
So here what i thought of splitting the schema and based on the selection i want to add the additional fields schema for the validation.
const required = () => "Field is required";
const resident_schema = object({
first_name: string().required(required).nullable(),
last_name: string().required(required).nullable(),
});
const non_resident_schema = object({
passport_number: string().required(required).nullable(),
country: object().required(required).nullable(),
state: object().required(required).nullable(),
});
const schemaBasedCitizen = {
RESIDENT: resident_schema,
NON-RESIDENT: non_resident_schema,
};
export const validationSchema = object().shape({
citizen: object().required(required).nullable(),
{ ...object().when("citizen", {
is: (value) => !!schemaBasedCitizen[value.toUpperCase()],
then: (value) => schemaBasedCitizen[value.toUpperCase()],
}) },
});
And my html consist of
<select>
<option disabled selected value> -- select an option -- </option>
<option value='resident'>Resident</option>
<option value='non-resident'>Non-Resident</option>
</select>
I am not able to spread, since key requires, So is there a way to achieve this.
Update
Schema when value is resident in select field
export const validationSchema = object().shape({
citizen: object().required(required).nullable(),
first_name: string().required(required).nullable(),
last_name: string().required(required).nullable(),
});
Schema when value is non-resident in select field
export const validationSchema = object().shape({
citizen: object().required(required).nullable(),
passport_number: string().required(required).nullable(),
country: object().required(required).nullable(),
state: object().required(required).nullable(),
});
Basically the validation is dynamic based on the value on citizen select field.
yup has this thing that it can only reference sibling fields (or context) using
when
.Your
citizen
field is NOT a sibling of the rest of the object and can't be used to conditionally change the object schema, it's a child of the object, so you can't reference it as a sibling field viawhen
.One way to accomplish what you want could be to use a lazy schema: