Formik: Update validation message conditionally

Created on 12 Apr 2019  路  2Comments  路  Source: formium/formik

鉂換uestion

I'm trying to write a schema where when the user selects an item from a dropdown, it checks whether the clicked item has an associated book or not. If it doesn't, the schema renders a message to the user.

    ItemID:
        Yup.string()
            .required("Item is required")
            .when("ItemID", (itemID: string, passSchema: any) => {
                const selectedItem = this.props.AllItems.find((i) => i.ID === itemID);

                // Check if selected item includes a book
                if (selectedItem.Book) {
                    // schema pass
                } else {
                    // render message "This item does not include a book."
                }
            }),

I've done the above but its throwing this error: Error: Cyclic dependency. I'm assuming its trying to validate the same field that's changing. How can I get around this?

Formik Support Redirect User Land Question

Most helpful comment

Instead of using when you can use test to write any generic validation. For example:

    .test(
      'itemIncludesBook',
      'This item does not include a book.',
      val => val == null || itemHasBook(val),
    )

All 2 comments

Instead of using when you can use test to write any generic validation. For example:

    .test(
      'itemIncludesBook',
      'This item does not include a book.',
      val => val == null || itemHasBook(val),
    )

Thank you so much. That did the trick. I wish the Yup documentation had better examples.

@marioharper So this is what I did:

.test("itemIncludesBook", "Selected item has no book", (value) => {
    // this if check is here because the first item in the dropdown is  "Please select an item"
    if (value !== undefined) {
        const selectedItem = this.props.AllItems.find((i) => i.ID === value);
        if (!selectedItem.Book) {
            return false; // validation only works if I return false
        }
    }
    return true;
})

I'm not sure what the purpose of the "itemIncludesBook" string is. Also, the validation only works I return false. I would've expected it to be the other way around. Can you shed some more light on this? Thanks.

Was this page helpful?
0 / 5 - 0 ratings