Validating a react-final-form form with yup and custom validations
Asked Answered
B

1

10

I have a form created with react-final-form and a validation function that looks like this

export const validate = async (values, schema) => {
  if (typeof schema === 'function')
    schema = schema();

  try {
    await schema.validate(values, { abortEarly: false });
  } catch (e) {
    return e.inner.reduce((errors, error) => {
      return setIn(errors, error.path, error.message);
    }, {});
  }
};

So when i render my form it looks something like this

<Form
  onSubmit={handleSubmit}
  validate={values => validate(values,schema())}
/>

Schema is a Yup schema that is defined as such

const schema = () =>

    yup.object().shape({
        name: yup
            .string()
            .max(255)
            .required(REQUIRED_FIELD),
        number: yup
            .string()
            .required(REQUIRED_FIELD),
        exp_year: yup
            .number()
            .required(REQUIRED_FIELD),
        exp_month: yup
            .number()
            .min(1,'Invalid')
            .max(12,'Invalid')
            .required(REQUIRED_FIELD),
        cvc: yup
            .number()
            .required(REQUIRED_FIELD),

    });

This works fine, as long as i use Yup methods, however, the credit card service i am using provides their own validation functions, such as 'Provider.validateCardNumber' from an external script.

What i cant seem to figure out is where and how to add custom validation so that i can continue to use the Yup validation for other fields, but my external library methods for custom validation of the cvc and credit card number.

Is there a way to add a custom callback function within my yup schema and return the value of the function such as my Provider.validateCardNumber within yup so i dont need to change my validate function? and if so, how can i access the values within the schema, which were passed to the validate function...

OR

how should i modify my validate function so that it will run the Yup schema validation, AND the external script validations, so in the end it returns an empty object to the validate prop of react-final-form

In other words, I want to run an external method as part of my validation, but continue using Yup schema if possible.

Baronial answered 7/10, 2019 at 23:55 Comment(2)
This is more of a Yup question, so I can't really help you much. All RFF cares about is that the errors be returned via a resolved Promise, like you're doing in your catch.Infective
Thanks Erik, indeed it was a Yup issue, and i managed to fix it using one of the yup methods, i just wasnt sure how to access the values but after a thorough check of their docs i found it!Baronial
B
14

The answer lies within the Yup documentation and their method test() so in the end i just needed to extend the schema and use the test method to be able to pass in an external true/false test

number: yup
            .string()
            .test('Card Test',
                'Invalid Card Number',
                value=>Provider.validateNumber(value)
            )
Baronial answered 9/10, 2019 at 13:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.