Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Yup - run async validation test only on value change

Tags:

reactjs

yup

Yup async validation test is getting called multiple times. Is there any way to call test only when there is change in value or prevent validation check for same value

    const validationSchema = yup.object().shape({
    zipCode: yup.string().required()
        .test('invalidZip', 'ZipCode must be valid', (value, context) => {
            /**
             * api call to validate zip code
             * this is getting called multiple times even though there is no change in 
             * zipCode.
             * I want to run this test only if there is change in value
             */
            return new Promise.resolve((resolve) => Utils.validateZipCode(value, resolve));
        })
});
like image 692
kailashthakuri Avatar asked Oct 18 '25 13:10

kailashthakuri


2 Answers

Sadly yup runs validation on all fields in schema no matter which one was changed. It is especially painful when you do remote calls in your yup tests (for instance REST request). This is known issue, see this thread for many workarounds https://github.com/jaredpalmer/formik/issues/512 . The one that I used is based on answer by thenameisflic and goes something like this:

const cacheTest = (asyncValidate: (val: string) => Promise<boolean>) => {
    let _valid = false;
    let _value = '';

    return async (value: string) => {
        if (value !== _value) {
            const response = await asyncValidate(value);
            _value = value;
            _valid = response;
            return response;
        }
        return _valid;
    };
};

const actualValidityTest = cacheTest(
    (value: string) => new Promise(
        (resolve) => yourTestLogic()
    )
);

and plug it in like this:

.test(
    'test_name',
    'some message',
    shopNameValidityTest
)

The main idea of the fix is that you cache previous value passed to test as well as previous validation result. If value did not change then return previous validation result. However, if verified value changed then run actual validation and cache result.

One nice thing about this solution is that it is pretty generic, you can wrap any of your tests in cacheTest and avoid unnecessary validations.

like image 101
iwek Avatar answered Oct 20 '25 03:10

iwek


https://github.com/jaredpalmer/formik/issues/512

mahj0ubiwael's answer here. document.activeElement.id. get the field id and use it in your

    .test(email,"err string",() => {
if(document.activeElement.id === "email"){
// Validate here
}
})
like image 37
sujai krishna Avatar answered Oct 20 '25 03:10

sujai krishna



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!