Typically, I avoid using JS app frameworks, and default to plain vanilla JavaScript. But, in keeping up with what is current – and working on projects as part of a team – React is inevitable: “A JavaScript library for building user interfaces” . Yup is the go-to form validation library in this context. Its GitHub page calls it “Dead simple Object schema validation”.
Yup creates validation schemas for inputs. Create a Yup validation object, and wire it up to a form – easy.
The ask
Setting: An existing React project, with a signup form. The form includes address inputs. The “country” input was not a required field – it could be left blank. My assignment was to make that field be required, only if the “state/territory” input was not empty. Sounds straight forward.
Here is a sample of the original code:
export const apValidateMyAddress = () => { name: yup.string().required("Don't leave this blank!!"), email: yup.string().email(), address: yup:string(), city: yup.string(), state: yup.string(), country: yup.string() }
At first, I wasn’t sure if I should update this schema code directly. I thought about checking if the state field was blank, or not, and applying a different schema object instead. That would have been the wrong approach.
Doing some research, I discovered that the Yup’s when() method was the solution. It would let me “adjust the schema based on a sibling or sibling children fields”.
My first attempt was wrong, and didn’t work::
export const apValidateMyAddress = () => { name: yup.string().required("Don't leave this blank!!"), email: yup.string().email(), address: yup:string(), city: yup.string(), state: yup.string(), country: yup.string().when('state',{ is: true, then: yup.string().required('This is a required field.') }) }
Errors were thrown. Documentation examples were hard to come by, and I was new at this. I wanted the condition to be true if “state” was not blank. Setting the “is” clause as “true” would only work if state was validated as a boolean – state: yup.boolean() . Ultimately, I was able to check that the “state” value existed using the value property:
export const apValidateMyAddress = () => { name: yup.string().required("Don't leave this blank!!"), email: yup.string().email(), address: yup:string(), city: yup.string(), state: yup.string(), country: yup.string().when('state',{ is: (value: any) => !!value, then: yup.string().required('This is a required field.') }) }