I'm trying to validate a email field on a sign up form to check if it already exist. To do this I'm checking the running a GET request on the server that returns true and false.
This is my validation Schema for the field:
validationSchema={
yup.object().shape({
registrationEmail: yup.string().email('Invalid email').test('Unique Email','Email already in use', async (value) => {axios.get('http://localhost:5000/users/register', value).catch(err => console.log(err)) })
})
}
The problem seems to be that the values field is blank. How do I past the value from the Formik Field to my function?
EDIT: Managed to send value using the following
registrationEmail: yup.string().email('Invalid email').test('Unique Email','Email already in use', function(value){return new Promise((resolve, reject) => {axios.get('http://localhost:5000/users/register', value)})})
I'm still having troubles returning a response this is what the route looks like
router.get('/register', (req, res) => {
User.findOne({email: req.body.email}).then(user => {
if(user){
return true
}else{
return false
}
})
})
After making an HTML form, you will need to check form validation, because there is no guarantee that the input given by the user is always correct. PHP can validate form input server side, submitted by the user using HTML forms. You need to check a few things: Numbers only.
Formik supports field-level validation via the validate prop of <Field> / <FastField> components or useField hook. This function can be synchronous or asynchronous (return a Promise). It will run after any onChange and onBlur by default.
Manually Triggering Validation You can manually trigger both form-level and field-level validation with Formik using the validateForm and validateField methods respectively. 1 import React from 'react'; 2 import { Formik, Form, Field } from 'formik';
Here comes Formik and Yup to the rescue! Formik is designed to manage forms with complex validation with ease. Formik supports synchronous and asynchronous form-level and field-level validation. Furthermore, it comes with baked-in support for schema-based form-level validation through Yup.
Yup validation schemas are created using Yup.object method which takes as a parameter an object. This object has the field names as properties and their values are validation rules from the Yup library. Then, add the property validationSchema to the object passed to useFormik with the following value:
Note: The <Field>/<FastField> components' validate function will only be executed on mounted fields. That is to say, if any of your fields unmount during the flow of your form (e.g. Material-UI's <Tabs> unmounts the previous <Tab> your user was on), those fields will not be validated during form validation/submission.
I solved my problem for the validation I did the following:
registrationEmail: yup.string().email('Invalid email')
.test('Unique Email','Email already in use',
function(value){return new Promise((resolve, reject) => {
axios.post('http://localhost:5000/users/register/validEmail', {'email': value})
.then(res => {if(res.data.msg === 'Username already been taken'){resolve(false)} resolve(true)})
})}
)
For the route:
router.post('/register/validEmail', (req, res) => {
console.log('Request: ', req.body)
User.findOne({email: req.body.email}).then(user => {
if(user){
console.log({ msg:"Username already been taken" })
return res.json({ msg:"Username already been taken" })
}
console.log({ msg: "Username available." })
return res.json({ msg: "Username available." })
}).catch((err)=>{
console.error(err);
res.status(400).json('Error: ' + err)
})
})
Turns out I had to use a POST request or the body of the request would be empty.
I noticed that you had used async/await in your question, but your answer used promises. I prefer async/await and initially thought that it wasn't supported by Yup for their test function because if your solution, but Yup does support async/await! Here's an example of my code for anyone that wants an example. There are also a few examples in the docs: https://github.com/jquense/yup#mixedtestname-string-message-string--function-test-function-schema
username: Yup.string()
.min(2, 'Too short, minimum 2 characters')
.max(50, 'Too long, maximum 50 characters')
.required('Required')
.test(
'username-backend-validation', // Name
'Username taken', // Msg
async (username) => {
// Res from backend will be flag at res.data.success, true for
// username good, false otherwise
const { data: { success } } = await axios.post(
"http://localhost:3001/api/users/register/validate-username",
{ username: username }
);
return success
}
)
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