I tried integrating the Yup's Schema validation with formik. But receiving error as yupError.inner is undefined
Here's a link to codesandbox!
I have'nt tried much. But found this bug report. which was later realized to be resolved. But still i'm recieving the same. Link to issue #1486!.
// VALIDATION SCHEMA
const formSchema = Yup.object().shape({
emailId: Yup.string("Enter a valid string")
.email("Please enter a valid Email ID")
.required("Need your Email ID, we won't spam you!"),
confirmMail: Yup.string("Enter a valid string")
.matches(Yup.ref("emailId"), "Email ID's are not matching")
.required("Please enter a valid mailid"),
mobileNo: Yup.number("Please enter number")
.max(10, "You've entered more than 10 numbers")
.min(10, "You've entered less than 10 numbers")
.required("Password is required"),
password: Yup.string("Enter a valid password").required(
"Password field is required"
),
confirmPassword: Yup.string("Enter a valid password").required(
"Password fields are not matching"
)
});
//Integration of Validation
<Formik
validate
initialValues={this.initialValues}
validationSchema={this.formSchema}
onSubmit={this.handleSubmit}
>
{props => this.renderForm(props)}
</Formik>
Recieving the error yupError.inner is undefined
Bumpup yup to latest and use mixed().test() instead of string().test()
example :
passwordConfirm: Yup.mixed().test('is-same', 'Passwords not match.', value => value === values.newPassword)
The issue is the custom validation for matching the e-mail fields. I made a fork here which I fixed using the method from this Github issue to add a custom validation method to Yup for comparing equality of fields, a feature which is apparently not well-supported.
Related
I have an email input and i want to validate that the user entered a specific email "abcd#fg.com" and if not to show specific error message "This email is not in our database". I am using zod validation to do that, but how can it be done?
const LoginSchema = z.object({
email: z
.string()
.min(1, { message: "This field has to be filled." })
.email("This is not a valid email.")
})
});
I can show how to do this, but I don't think this should be done (more later).
You can use refine to check if the string is exactly some expected value. For example:
const LoginSchema = z.object({
email: z
.string()
.min(1, { message: "This field has to be filled." })
.email("This is not a valid email.")
.refine((e) => e === "abcd#fg.com", "This email is not in our database")
});
Then, later if you were going to pull down emails so you can write a validation on the frontend you would use an async refinement with parseAsync like:
const login2 = z.object({
email: z
.string()
.min(1, { message: "This field has to be filled." })
.email("This is not a valid email.")
.refine(async (e) => {
const emails = await fetchEmails();
return emails.includes(e);
}, "This email is not in our database")
});
Opinion Warning
I would not recommend doing this for 2 reasons:
The number of emails is likely to be very large if you have any meaningful number of users. Pulling all of those down just to make this check would be a pretty big waste of resources and time.
Security wise, sharing emails of all your users publicly over the API strikes me as a dangerous thing to do. Anyone would hit that API to get real email addresses for all of your users.
I would recommend not validating this as part of the data validation. This validation should happen on the backend and return a 4XX error response when logging in.
Edit
A comment on this post mentioned that you could instead provide an API to validate an email address. This could be safely used from an async refinement and avoids the issues described above.
That would look like:
const login2 = z.object({
email: z
.string()
.min(1, { message: "This field has to be filled." })
.email("This is not a valid email.")
.refine(async (e) => {
// Where checkIfEmailIsValid makes a request to the backend
// to see if the email is valid.
return await checkIfEmailIsValid(e);
}, "This email is not in our database")
});
Confirm password validation is not working here and also error is not showing until I submit it.
const schema = joi
.object({
fullName: joi.string().min(5).max(255).required(),
username: joi.string().min(5).max(255).required(),
email: joi
.string()
.email({ tlds: { allow: false } })
.pattern(new RegExp(patternForEmail))
.message('Invalid email address')
.required(),
password: joi
.string()
.pattern(new RegExp(patternForPassword))
.message(
'Password must contain at least one lowercase letter, one uppercase letter, one number and one special character and minimal length of 8 characters'
)
.required(),
confirmPassword: joi.string().required().valid(joi.ref('password')),
})
.with('password', 'confirmPassword');
check the full code here
import Auth from '#aws-amplify/auth';
await Auth.signUp({
username,
password,
attributes: {email, phone_number: phoneNumber}
})
assume 'phoneNumber' is a user-dependent input.
many (most) inputs will cause failure.
What is the most practical method for validation of 'phoneNumber' prior to Auth.signUp ?
Additionally, why does failure manifest as such in React Native?:
Using joi on the server side, I can do multiple validations like
id: [joi.string().email(), joi.string().min(10)].
How can we do this on frontend using formik and yup? I went through the docs and still no success.
You should try Yup like this.
const formikEnhancer = withFormik({
validationSchema: Yup.object().shape({
name: Yup.string().strict(true).lowercase('Name must be lowercase').matches(/^\S+$/, 'Name must not contain spaces').matches(/^(?:(?!\.).)*$\r?\n?/, 'Name must not contain period').max(10, 'Maximum of 10 characters')
.required('Name is required!'),
email: Yup.string().strict(true).lowercase('Email must be lowercase').required('Email is required!')
})
})
Repeating the title, my question is how to test for form submission using "Enter Key" using poltergeist through capybara. In other words, i expect when i fill in the username, password and then press "Enter" while on either input i'll submit the form. From what I can tell poltergeist achieves this through "send_keys". However my current test:
When(/^I log in with enter key$/) do
visit_login
fill_in "app-email", :with => admin_user.email
fill_in "app-password", :with => admin_user.password
login = find("#app-password")
login.native.send_key :Enter
end
works with the following (original) code which uses ng-click. I expected the above test to fail on the code below as with the code below you can't hit enter and submit the form in the browser. Here is the ng-click code:
%form{name: "form"}
%input#app-email{name: "email", "ng-model" => "email", type: 'email'}
%input#app-password{name: "password", "ng-model" => "password", type: "password"}
%a.btn.btn-primary.login-btn#app-login{"ng-click" => "login(email, password)"} LOG IN
and here is the code with ng-submit, this both works manually and with the test:
%form{name: "form", "ng-submit" => "login(email, password)"}
%input#app-email{name: "email", "ng-model" => "email", type: 'email'}
%input#app-password{name: "password", "ng-model" => "password", type: "password"}
%input.btn.btn-primary.login-btn#app-login{type: "submit", value: "LOG IN"}
there is a rather lengthy discussion on getting this to work here: Is there a way to send key presses to Webkit using Capybara?. However, I couldn't modify any of those solutions to work for me.