I am trying async validation in Formik using Yup's .test()
method and need to set the error message that I get from the API. Error messages are going to be different based on some conditions in backend.
Tried few solutions mentioned here
https://github.com/jquense/yup/issues/222 and Dynamic Validation Messages Using Yup and Typescript
But Yup is throwing the default error message given in test()
.
Documentation says that
All tests must provide a name, an error message and a validation function that must return true or false or a ValidationError. To make a test async return a promise that resolves true or false or a ValidationError.
I am resolving a new ValidationError with the error message but still, it throws the default error.
Here is the code.
const schema = Yup.object().shape({
email: Yup.string().test(
"email_async_validation",
"Email Validation Error", // YUP always throws this error
value => {
return new Promise((resolve, reject) => {
emailValidationApi(value)
.then(res => {
const { message } = res.data; // I want this error message to be shown in form.
resolve(new Yup.ValidationError(message));
})
.catch(e => {
console.log(e);
});
});
}
)
});
I got it working using the function
syntax instead of arrow function for validation function.
Doc says:
test functions are called with a special context, or
this
value, that exposes some useful metadata and functions. Note that to usethis
context, the test function must be a function expression(function test(value) {})
, not an arrow function, since arrow functions have lexical context.
Here is the working code.
const schema = Yup.object().shape({
email: Yup.string()
.email("Not a valid email")
.required("Required")
.test("email_async_validation", "Email Validation Error", function (value) { // Use function
return emailValidationApi(value)
.then((res) => {
const message = res;
console.log("API Response:", message);
return this.createError({ message: message });
// return Promise.resolve(this.createError({ message: message })); // This also works
})
.catch((e) => {
console.log(e);
});
})
});
Actually you're almost correct.You just need to use the following:
resolve(this.createError({ message: message }));
Let me know if it still doesn't work ya
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With