I have the following code:
<Formik
initialValues={{
name: '',
email: '',
password: '',
passwordConfirmation: '',
}}
validationSchema={Yup.object(
{
name: Yup.string()
.required('Required'),
email: Yup.string()
.email('Invalid email address')
.required('Required')
.when('email', {
is: true,
then: Yup.string().test(
'checkEmailAvailability',
'An account with this email already exists',
async (value) => {
const auth = getAuth();
const signInMethods = await fetchSignInMethodsForEmail(
auth,
value
);
if (signInMethods.length) return false;
return true;
}
),
}),
password: Yup.string()
.min(6, 'Must be at least 6 characters')
.required('Required'),
passwordConfirmation: Yup.string().oneOf(
[Yup.ref('password'), null],
"Passwords don't match"
),
},
['email']
)}
onSubmit={(values, { setSubmitting }) => {
...
}}
This is Formik using Yup to validate whether email already exists in a Firebase database. The initial problem I encountered after writing a test is that all validations were ran at the same time which caused Firebase to throw an Error. I tried to solve this issue by adding when. I am unsure whether this conditional test works (namely whether then: Yup.string().test(... is valid) because when executing I get the Error: Cyclic dependency, node was:"email" error. Solutions for this problem suggest adding dependency array at the end of the script, which I did.. however, this did not solve the issue.
I'm stuck and ran out of ideas. How can I make this code work to get what I need?
The problem was my solution doesn't make sense because the field depends on itself and there's no way out of this.
Unfortunately, as far as I know Yup doesn't provide a clean solution for .test being called asynchronously, which results in either a needless call to the database or throws an error like in my case.
For solving the issue, I used the following solution: How to set dynamic error messages in Yup async validation?.
I wrote a function which checks synchronously for: empty field, invalid format and whether e-mail exists in the database and used above linked solution to display the error.
It's very counterintuitive to write a separate function to handle form validation in Yup since Yup already has methods for that.. but as you can see, it's not perfect.