Yup: dynamic required fields and asterisks on input labels

Created on 20 Apr 2018  路  5Comments  路  Source: jquense/yup

I have a schema for an address like this:

export const AddressSchema = object().shape(
    {
        country: string().required(),
        zip: string().required(),
        city: string().required(),
        street: string()
            .when('poBox', {
                is: (e) => !e,
                then: string().required()
            }),
        number: string()
            .when('street'.toString(), {
                is: (e) => e,
                then: string().required()
            }),
        poBox: string()
            .when('street', {
                is: (e) => !e,
                then: string().required()
            }),
    },
    [['street', 'poBox']]
);

The user has to enter street and number or the post office box. Now I want to add asterisks to the labels of the input fields dynamically. That means, when the input fields for street, number and poBox are empty, there are asterisks at all there 3 labels. When the user enters a PO box, the asterisks at street and number disappear.

The question is, how can we 'calculate' whether a specific field is required for the current form values?

Most helpful comment

For future generations:

reach(validationSchema, 'my.deep.object', currentValues).describe();

The resulting object contains tests objects which has the data you need.

Passing currentValues is important if your schema is dynamic (using when/lazy etc).

All 5 comments

You can use schema.describe() to introspect a schema object.

For future generations:

reach(validationSchema, 'my.deep.object', currentValues).describe();

The resulting object contains tests objects which has the data you need.

Passing currentValues is important if your schema is dynamic (using when/lazy etc).

I tried describe() before, but had no success.
The combination of reach and describe did the trick. Thanks.

I was trying to do this exact thing. Doing a lot of searching after it didn't work led me to:

reach() no longer resolves the returned schema meaning it's conditions have not been processed yet; prefer validateAt/castAt where it makes sense

This is a pretty important feature for accessibility. It doesn't seem like validateAt/castAt make sense for this use case. Is there some other way we can do this now that the above change has been made?

I ended up implementing this by doing the reach and then calling resolve({ value: ... }) on the returned schema. Basically doing what reach _used_ to do.

Was this page helpful?
0 / 5 - 0 ratings