Validate only one single field of a bigger Joi schema - javascript

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');

Related

JOI Verification is accepting invalid inputs

As you can see in my console log, the validation schema is working when I lead the input with an illegal character. However, if the illegal character is between legal ones, it wrongly verifies the input.
const UserLoginSchema = Joi.object({
username: Joi.string()
.required()
.min(3)
.max(30)
.pattern(new RegExp(`^[a-zA-Z0-9_.]`)),
password: Joi.string()
.min(6)
.required()
.min(6)
.max(30)
.pattern(new RegExp(`^[a-zA-Z0-9_.+-]+$`)),
});

Joi validate one of two schemas

I have a simple object with few fields that I would like to validate. I wish to allow or a specific validation schema or that all of the properties have empty values
I created the following two schemas:
const nonEmptyUserInfoValidationSchema = Joi.object({
url: Joi.string().uri().required(),
username: Joi.string().required().min(usernameMinLength),
password: Joi.string().required().min(passwordMinLength),
});
const emptyUserInfoValidationSchema = Joi.object({
url: Joi.string().empty().required(),
username: Joi.string().empty().required(),
password: Joi.string().empty().required(),
});
I wish to create schema that validates if emptyUserInfoValidationSchema or nonEmptyUserInfoValidationSchema is applied but I can't figure out how to do it, any suggestions?
allowed:
{url:"http://some.url", username:"some username", password:"some password"}
{url:"", username:"", password:""}
not allowed:
{url:"http://some.url", username:"", password:""}
Well I finally found what I was looking for joi.alternatives:
export const ansibleInfoValidationSchema = Joi.alternatives(emptyUserInfoValidationSchema , nonEmptyUserInfoValidationSchema );
seems to do the trick
You use the .keys().and() to specify peers. This means that none of the fields specified in the .and() will exist without each other. Hence should be used as so:
const schema = Joi.object({
url: Joi.string().uri(),
username: Joi.string().min(usernameMinLength),
password: Joi.string().min(passwordMinLength)
}).keys().and('url', 'username', 'password');
I hope this helps you can use the when condition in Joi
var schema = Joi.object({
url : Joi.any().when('username',{
is: Joi.empty(),
then: Joi.empty().required(),
otherwise: Joi.string().required()
}),
username: Joi.when('password',{
is: Joi.empty(),
then: Joi.empty(),
otherwise: Joi.string().required().min(usernameMinLength)
})
});
here's a link to when docs Joi When Condtion

React Yup schema

I'm using Yup to validate an email field:
const Schema = Yup.object().shape({
email: Yup.string()
.email("non valid email format")
.required("Email required"),
...
During form submit, I check if the email domain is included in a list of forbidden domains, if yes, I display an error message in a popup:
const forbidDomains = domains;
const domain = data.email.split("#");
if(forbidDomains.Domains.includes(domain[1])) {
this.setState({openPopup:true,statusMessage:"domain not allowed : " + domain[1]})
this.setState({isSubmitting:false})
return;
}
I would like to check the domain in the Yup schema, but I'm not sure if it's possible.
I think that what you are looking for is the .test() from Yup. Maybe something like this may work:
const schema = {
email: Yup.string()
.string()
.email()
.test('test-name', 'Validation failure message',
function(value) {
// your logic to check the domain
})
}

Access to required fields with Yup

I use react-hook-form with yup to validate my forms.
I want to know all required fields of a schema to display some information in form (like '*' for required fields).
We could achieve this with this line of code :
schema.describe().fields[field].tests.findIndex(({ name }) => name === 'required'
However, this code doesn't work for conditional validation.
Schema example :
const schema = yup.object().shape({
email: yup
.string()
.email()
.required(),
isProfileRequired: yup
.boolean(),
profile: yup
.object()
.when('isProfileRequired',{
is: (isProfileRequired) => isProfileRequired,
then:
yup
.object()
.nullable()
.required()
})
})
Is there a way to retrieve this informations within the form ?
There is actually no "nice" way to do it but this works:
function isRequired(field){
return schema.fields[field]._exclusive.required || false
}
Notice: schema.fields[field]._exclusive.required returns true if required or undefined.
Testing exclusiveTests instead of _exclusive worked for me.
const isRequired =
validationSchema?.fields[aField.name]?.exclusiveTests?.required || false;

Joi Schema should contain one field or another

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.

Categories