1

I have this validation:

    ticket: yup
      .number()
      .required(I18n.t("is_required"))
      .when([], {
        is: () => {
          return timeFramedExperience;
        },
        then: yup.number().nullable(),
      }),
    max_p: yup
      .number()
      .required(I18n.t("is_required"))
      .when([], {
        is: () => {
          return timeFramed;
        },
        then: yup.number().nullable(),
      }),

timeFramed is a react hook state set to true. I want these fields, max_p and ticket to not be required when timeFramed is true.

but, on submit, I get this error:

Cannot read properties of undefined (reading 'reduce')
c0m1t
  • 1,089
  • 1
  • 7
  • 16
Gotey
  • 449
  • 4
  • 15
  • 41
  • Possibly duplicate of [this](https://stackoverflow.com/questions/49394391/conditional-validation-in-yup) or [this](https://stackoverflow.com/questions/54919228/conditional-validation-with-yup-and-formik). – c0m1t Nov 10 '22 at 14:02
  • in my case I want to use a react hook state to decide on the condition, not a form registered field – Gotey Nov 10 '22 at 15:16
  • 1
    In that case you could add the state as a field, or use `yup context`. [Here](https://codesandbox.io/s/react-hook-form-yup-resolver-forked-z4s98k?file=/src/App.js) is an example that might help you. See [yup documentation](https://github.com/jquense/yup/tree/v0.32.11#mixedwhenkeys-string--arraystring-builder-object--value-schema-schema-schema). – c0m1t Nov 10 '22 at 15:44
  • I'll check that. I was able to solve it creating two schemas and concatenating them based on that condition – Gotey Nov 10 '22 at 16:00
  • @c0m1t Incorrect. Your references are questions on conditionals using other form fields. As the OP suggested, (and what I'm also trying to achieve) is conditionals based on outside variables, such as state. – anastymous May 08 '23 at 22:15
  • @anastymous I have provided a [codesandbox](https://codesandbox.io/s/react-hook-form-yup-resolver-forked-z4s98k?file=/src/App.js) in the comment above which uses yup context. In the provided code, `checked` is a state variable that is passed as a context to yup. `checked` is not part of the yup schema or form. It can be a variable sourced from props or state. – c0m1t Jun 07 '23 at 10:34

1 Answers1

3
  1. Use different schemas as OP mentioned:
   condition ? : schema1 : schema2
  1. Use yup context:
   yup
   .string()
   .when("$condition", (condition, schema) =>
     condition ? schema : schema.required()
     // Here `condition` is passed as context to yup.
   )
  1. Use a hidden field or add the state to the form somehow.

I created a codesandbox which uses react-hook-form and yup to validate and has implemented the 3 solutions mentioned above.

If your state may change during the time user is filling in the form, be careful about calling trigger. Calling trigger before your state updates in the next render could lead to bugs.

c0m1t
  • 1,089
  • 1
  • 7
  • 16