0
votes

I created a custom Yup validation using .test().

// users is an array of strings
user: Yup.string().test(
  "user-check",
  "At lease one user should be added",
  () => users.length > 0
)

The goal is to validate the form when at least one user is added. An input field let you type a username (any string value) then you click a button to add it to a list.

The validation is working well after adding the 2nd username (or adding the 1st one then start typing on the field). I'm sharing this live Demo: https://codesandbox.io/s/hopeful-goldwasser-shpbk

Steps to reproduce

  1. Click on the text field.
  2. Type a username.
  3. Click the red button.

Expected

  • The form should be valid.

What you'll get

  • The form is invalid

Any feedback about this strange behavior?

Remark

  • I'm not sure if this is the origin of the problem.

  • The first time you add a user, the validation is called 2 times: the 1st time with an empty users array and then with the correct users value (which is the user you added)!

2

2 Answers

1
votes

The scope of your Formik form currently contains only the input field for a user. The array with users is currently not part of your form (not included in the initial values). There are two thinks you could do:

  • Move users array into your Formik scope. Work with FieldArray (https://jaredpalmer.com/formik/docs/api/fieldarray) for example. Then you can do the validation like you try to do now.
  • Do the validation manually when running onSubmit. For example like this:
  const onSubmit = () => {
    if (users.length > 0) {
       // there are some users (form is valid) -> do API call or whatever necessary
    } else {
       // no users (form is not valid) -> display some error
    }
  };

You could even just disable the submit button like this (event it is not the correct way if working with Formik):

<input type="submit" value="Submit" disabled={users.length === 0} />

I hope this helps. If you have any questions, let me know and I can update my answer.

0
votes

try user: Yup.string().test( "user-check", "At lease one user should be added", async (users) => await users.length > 0 )