I would like to make the email value not required when status is equal to "Prospect", how can I do it? This is what I've tried so far.
status: Joi.string()
.required(),
email: Joi.string()
.email({ tlds: { allow: false } })
.when('status', { is: Joi.not('Prospect'), then: Joi.required() })
Hi I am using "#hapi/joi": "^15.1.1". Unfortunately, I can't update to the latest Joi version right now.
This is my validation schema
const schema = {
name: Joi.string()
.allow("")
.max(30),
addLine1: Joi.string()
.required()
.label("Address Line 1"),
locality: Joi.string()
.required()
.label("City"),
region: Joi.string()
.required()
.label("State"),
zipCode: Joi.number()
.required()
.label("Zip Code"),
phoneNo: Joi.string()
.required("Required")
.regex(/^[0-9]{3}\-[0-9]{3}\-[0-9]{4}$/)
};
Then I validate and display the first error that occurred
const result = Joi.validate(this.state.addressDetails, this.schema, {
abortEarly: true,
});
return const errors = result.error.details[0].message;
This works. The only problem is I want to display a custom error message instead of the default one.
Default error message for address is "Address Line 1" is not allowed to be empty"
Instead of this, I want to display "Address is required!"
For the regex default one is
phoneNo with value "555" fails to match the required pattern: /^[0-9]{3}\-[0-9]{3}\-[0-9]{4}$/
Instead, I want to display please enter a valid phone number
How could I achieve this with version 15.1.1.
Newer versions messages thing won't help here.
Try out to return the message from the .error callback
addLine1: Joi.string()
.required()
.label("Address Line 1").error(()=>'"Address Line 1" is not allowed to be empty'),
I want to use Joi for form field validation and want to stick with one big schema object for validation of the whole form, yet I want to run single entry validation after one form field has been changed - i.e. after the first form field has recieved a value, I do not want to validate the complete form, but only the one field updated. I am envisioning something like
const schema = Joi.object({
username: Joi.string()
.alphanum()
.min(3)
.max(30)
.required(),
password: Joi.string()
.pattern(new RegExp('^[a-zA-Z0-9]{3,30}$'))
.required(),
});
const validationResult = schema.username.validate('Tommy');
Is that possible?
Yes, by extracting the username schema to a separate schema like so:
const username_schema = Joi.string()
.alphanum()
.min(3)
.max(30)
.required();
const schema = Joi.object({
username: username_schema,
password: Joi.string()
.pattern(new RegExp('^[a-zA-Z0-9]{3,30}$'))
.required(),
});
const validationResult = username_schema.validate('Tommy');
I have an email field that only gets shown if a checkbox is selected (boolean value is true). When the form get submitted, I only what this field to be required if the checkbox is checked (boolean is true).
This is what I've tried so far:
const validationSchema = yup.object().shape({
email: yup
.string()
.email()
.label('Email')
.when('showEmail', {
is: true,
then: yup.string().required('Must enter email address'),
}),
})
I've tried several other variations, but I get errors from Formik and Yup:
Uncaught (in promise) TypeError: Cannot read property 'length' of undefined
at yupToFormErrors (formik.es6.js:6198)
at formik.es6.js:5933
at <anonymous>
yupToFormErrors # formik.es6.js:6198
And I get validation errors from Yup as well. What am I doing wrong?
You probably aren't defining a validation rule for the showEmail field.
I've done a CodeSandox to test it out and as soon as I added:
showEmail: yup.boolean()
The form started validation correctly and no error was thrown.
This is the url: https://codesandbox.io/s/74z4px0k8q
And for future this was the correct validation schema:
validationSchema={yup.object().shape({
showEmail: yup.boolean(),
email: yup
.string()
.email()
.when("showEmail", {
is: true,
then: yup.string().required("Must enter email address")
})
})
}
Formik author here...
To make Yup.when work properly, you would have to add showEmail to initialValues and to your Yup schema shape.
In general, when using validationSchema, it is best practices to ensure that all of you form's fields have initial values so that Yup can see them immediately.
The result would look like:
<Formik
initialValues={{ email: '', showEmail: false }}
validationSchema={Yup.object().shape({
showEmail: Yup.boolean(),
email: Yup
.string()
.email()
.when("showEmail", {
is: true,
then: Yup.string().required("Must enter email address")
})
})
}
/>
You can even use a function for complex cases . Function case helps for complex validations
validationSchema={yup.object().shape({
showEmail: yup.boolean(),
email: yup
.string()
.email()
.when("showEmail", (showEmail, schema) => {
if(showEmail)
return schema.required("Must enter email address")
return schema
})
})
}
Totally agree with #João Cunha's answer. Just a supplement for the use case of Radio button.
When we use radio button as condition, we can check value of string instead of boolean. e.g. is: 'Phone'
const ValidationSchema = Yup.object().shape({
// This is the radio button.
preferredContact: Yup.string()
.required('Preferred contact is required.'),
// This is the input field.
contactPhone: Yup.string()
.when('preferredContact', {
is: 'Phone',
then: Yup.string()
.required('Phone number is required.'),
}),
// This is another input field.
contactEmail: Yup.string()
.when('preferredContact', {
is: 'Email',
then: Yup.string()
.email('Please use a valid email address.')
.required('Email address is required.'),
}),
});
This the radio button written in ReactJS, onChange method is the key to trigger the condition checking.
<label>
<input
name="preferredContact" type="radio" value="Email"
checked={this.state.preferredContact == 'Email'}
onChange={() => this.handleRadioButtonChange('Email', setFieldValue)}
/>
Email
</label>
<label>
<input
name="preferredContact" type="radio" value="Phone"
checked={this.state.preferredContact == 'Phone'}
onChange={() => this.handleRadioButtonChange('Phone', setFieldValue)}
/>
Phone
</label>
And here's the callback function when radio button get changed. if we are using Formik, setFieldValue is the way to go.
handleRadioButtonChange(value, setFieldValue) {
this.setState({'preferredContact': value});
setFieldValue('preferredContact', value);
}
email: Yup.string()
.when(['showEmail', 'anotherField'], {
is: (showEmail, anotherField) => {
return (showEmail && anotherField);
},
then: Yup.string().required('Must enter email address')
}),
it works for me very well :
Yup.object().shape({
voyageStartDate:Yup.date(),
voyageEndDate:Yup.date()
.when(
'voyageStartDate',
(voyageStartDate, schema) => (moment(voyageStartDate).isValid() ? schema.min(voyageStartDate) : schema),
),
})
I use yup with vee-validate
vee-validate
here is the sample code from project
const schema = yup.object({
first_name: yup.string().required().max(45).label('Name'),
last_name: yup.string().required().max(45).label('Last name'),
email: yup.string().email().required().max(255).label('Email'),
self_user: yup.boolean(),
company_id: yup.number()
.when('self_user', {
is: false,
then: yup.number().required()
})
})
const { validate, resetForm } = useForm({
validationSchema: schema,
initialValues: {
self_user: true
}
})
const {
value: self_user
} = useField('self_user')
const handleSelfUserChange = () => {
self_user.value = !self_user.value
}
I'm looking into using Joi for api validation.
I can't seem to confirm whether my schema is correct in that I want either the email or mobile to be required (but they both can't be empty/non existent) - is the below correct?
var schemaForRegistration = Joi.object().keys({
email: Joi.string().email(),
mobile:Joi.number().integer()
}).without('email', 'mobile');
Thanks
It might be that or() is what you're after.
Try this:
const Joi = require('joi')
const schema = Joi.object().keys({
email: Joi.string().email(),
mobile: Joi.number().integer()
}).or('email', 'mobile')
Joi.validate({ email: 'xxx#yyy.com', mobile: '999000999000' }, schema, console.log)
Joi.validate({ mobile: '999000999000' }, schema, console.log)
Joi.validate({ email: 'xxx#yyy.com' }, schema, console.log)
Joi.validate({}, schema, console.log)
The final validation will fail because neither email nor mobile is present.