React-final-form: Recommended validation library

Created on 21 Dec 2017  ·  14Comments  ·  Source: final-form/react-final-form

Hey there 👋 . What do you recommend for the validation library?
Formik recommends yup, just curious what final-form does recommend.

Keep up the good work ❤️

Most helpful comment

@bogdansoare

This might help?

<Form
        onSubmit={this.submitHandler}
        validate={async (values) => {
          const validator = validationSchema(values)

          try {
            await validator.validate(values, { abortEarly: false })
          } catch (err) {
            const errors = err.inner.reduce((formError, innerError) => ({
              ...formError,
              [innerError.path]: innerError.message
            }), {})

            return errors
          }
        }}

All 14 comments

🏁Final Form is unopinionated. Yup should work fine.

Here's a list of some that work with Redux-Form and should work fine with 🏁React Final Form.

@erikras I'm struggling implementing validation with yup, could you please provide a simple example ? it would really help, thanks.

@bogdansoare

This might help?

<Form
        onSubmit={this.submitHandler}
        validate={async (values) => {
          const validator = validationSchema(values)

          try {
            await validator.validate(values, { abortEarly: false })
          } catch (err) {
            const errors = err.inner.reduce((formError, innerError) => ({
              ...formError,
              [innerError.path]: innerError.message
            }), {})

            return errors
          }
        }}

Thanks for asking for help with yup, I was also looking for same.

Took the above (edit and the below) and turned it into a simple function.

import {Schema} from 'yup';
import {set, get} from 'lodash';

export function makeValidate<T>(validator: Schema<T>) {
    return async (values: T) => {
        try {
            await validator.validate(values, {abortEarly: false})
        } catch (err) {
            return err.inner.reduce((errors: any, {path, message}: any) => {
                if (errors.hasOwnProperty(path)) {
                    set(errors, path, get(errors, path) + ' ' + message);
                } else {
                    set(errors, path, message);
                }
                return errors;
            }, {});
        }
    };
}
const schema = yup.object().shape<InvoiceInput>(
    {
        name: yup.string().required().label('Invoice name'),
    }
);
const validate = makeValidate<InvoiceInput>(schema);

Hopefully this saves someone 10 minutes. Note that InvoiceInput was auto generated from my graphql schema. It would be nice if I could pass a typescript type into yup and have it magically generate a schema from that, but not the end of the world to write it out twice, at least it is typesafe.

Also, if you're integrating with MUI, you can use your definitions to set the required attribute on your wrapped <Field/>/<TextField/> by using yup.describe(). Actually, that is a lie, right now it is ugly, but I'm hoping the API for that gets better. Right now I'm using schema.fields[name]._exclusive.required

@lookfirst that reduce doesn't work with nested or field arrays, I used to do that way to, it is setting innerError.path. We have to actually set the shape that the path says. I use lodash set:

import { get, set } from 'lodash';

function convertYupErrorsToFieldErrors(yupErrors) {
  return yupErrors.inner.reduce((errors, { path, message }) => {
    if (get(errors, path)) {
        set(errors, path, get(errors, path) + ' ' + message);
    } else {
        set(errors, path, message);
    }
    return errors;
  }, {});
}

Thanks @Noitidart Working flawlessly!

I added this without the lodash dependency to my Material UI + RFF library...

https://github.com/lookfirst/mui-rff#helpers
https://github.com/lookfirst/mui-rff/blob/master/src/Validation.ts

Thanks @ziaulrehman40 ! There was a bug in that, the if (errors.hasOwnProperty(path)) I had to change to use lodash get as well.

@lookfirst we should be able to remove the lodash dependency as final-form exports some helpers:

Thanks @Noitidart ... that is helpful... I can use those instead of my own versions and save some bytes....

@Noitidart I tried them as a drop in replacement and my tests are failing. I'll have to dig into it deeper to see what is going on, but wanted to let you know that they don't seem to be a direct easy replacement.

Thanks please share your final solution.

On Tue, Nov 26, 2019 at 5:52 AM Jon Stevens notifications@github.com
wrote:

@Noitidart https://github.com/Noitidart I tried them as a drop in
replacement and my tests are failing. I'll have to dig into it deeper to
see what is going on, but wanted to let you know that they don't seem to be
a direct easy replacement.


You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/final-form/react-final-form/issues/78?email_source=notifications&email_token=ABQTZCLPW2MZDOD3RS726RDQVUSY7A5CNFSM4EJJSSUKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEFGCFIY#issuecomment-558637731,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABQTZCIUBYIWXSQTKUVYZKDQVUSY7ANCNFSM4EJJSSUA
.

@Noitidart any news with a final solution?

For anyone out there interested in using yup with RFF and landing on this issue, here's my take on a hook that would allow just that.

More than happy to add this to the docs if there's any interest.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

kiliw picture kiliw  ·  4Comments

antoinerousseau picture antoinerousseau  ·  3Comments

Noisycall picture Noisycall  ·  4Comments

3dos picture 3dos  ·  3Comments

CodeWithOz picture CodeWithOz  ·  4Comments