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
Related
I'm trying to add conidial schema according of the value of the isCat field in the request body, here is what I have so far:
ror [ERR_ASSERTION]: Invalid schema content` error.What am I missing? Thanks.
Try this
Joi.object({
params: Joi.object({
id: Joi.number().required().integer().min(1),
}),
body: Joi.object({
code: Joi.string().required(),
}).when(Joi.ref("$isValid"), {
is: Joi.equal(true),
then: Joi.object({
body: Joi.object({
...entity,
}),
}),
otherwise: Joi.object({
body: Joi.object({
...put,
}),
}),
}),
});
Verify the reference given by you is right Joi.ref("$isValid").
If you provide right reference, this schema will work as you expect.
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'm not able to set the joi-schema that it is working as expected...
This is what I try to do:
'role' is an array and can contain items as string. Any value is allowed.
But when 'internal' is set to 'true', only certain values in 'role' are allowed.
This is the code, which is not working as expected.
let Joi = require("#hapi/joi");
const schema = Joi.object({
internal: Joi.boolean(),
role:
Joi.array()
.items(Joi.string().trim())
.required()
// the when condition is not replacing properly
.when('internal', {
is: true,
then: Joi.array()
.items(Joi.string().valid("Admin"))
.required()
}),
});
console.log(schema.validate({role: ["Any Role"]})) // OK
console.log(schema.validate({internal: false, role: ["Any role allowed"]})) // OK
console.log(schema.validate({internal: true, role: ["WRONG"]})) // FAIL, should have thrown error
... while the replacing array function by itself works fine:
const passingschema = Joi.object({
role: Joi.array()
.items(Joi.string().valid("Admin"))
.required()
})
console.log(passingschema.validate({role: ["Admin"]})) // OK
console.log(passingschema.validate({role: ["WRONG"]})) // OK - throws error as expected
});
Please let me know, how to replace the role validation accordingly, once internal is set to true.
Maybe try is: valid(true).required() in the documentation it says you need required() on the is in order to make this work.
According to this link, this is the solution:
Joi.array().required()
.when('internal', {
is: true,
then: Joi.array().items(Joi.string().valid("Admin")),
otherwise: Joi.array().items(Joi.string())
})
I creating a register form and the problems accurs while try validating password confirmation. I am using the last version of JOI-Browser.
I tried the code below and the validation error was triggered even though password and password confirmation have the same values.
password: Joi.string()
.min(5)
.required(),
passwordConfirmation: Joi.ref("password")
Here is my state object:
password: "12345"
passwordConfirmation: "12345"
username: ""
errors: {…}
passwordConfirmation: "\"passwordConfirmation\" must be one of [ref:password]"
I passed several hours trying several approaches and reading the documentation, but still no luck, the validation is still triggering,
I have other validations in this form and they work fine.
I don't think Joi.ref should be used that way.
I usually tend to do this way:
const passwordConfirmation = Joi.string()
.required()
.valid(Joi.ref('password'))
.options({
language: {
any: {
allowOnly: '!!Passwords do not match',
}
}
})
If you refer to the docs, you will see:
Note that references can only be used where explicitly supported such as in valid() or invalid() rules. If upwards (parents) references are needed, use object.assert().
If anyone has encountered a similar problem, this is the solution I have used:
validateProperty = (input) => {
let obj = { [input.name]: input.value };
let schema = { [input.name]: this.schema[input.name] };
if (input.name.endsWith("_confirm")) {
const dependentInput = input.name.substring(
0,
input.name.indexOf("_confirm")
);
obj[dependentInput] = this.state.data[dependentInput];
schema[dependentInput] = this.schema[dependentInput];
}
const { error } = Joi.validate(obj, schema);
return error ? error.details[0].message : null;
};
In my case, I have looked for _confirm because I have the field names as password and password_confirm. You need to make changes here as per your requirements.
Main logic, you just need to add value and schema of password when you are validating password_confirm
I find out what was happening. My code above was right, the problem was in my validate function.
Gabriele's Petrioli comment help me out. this is the function that cause me problems:
validateProperty = ({ name: propertyName, value }) => {
const obj = { [propertyName]: value };
const schema = { [propertyName]: this.schema[propertyName] };
const { error } = Joi.validate(obj, schema);
return error ? error.details[0].message : null;};
Has you can see i tried validate each property individually, so i can make the form more dynamic.
This trigger the validation error because when i try to validate confirmPassword there was no value in password because i passed only the value the correspond to confirmaPassword, it also needed the password value to make the comparison.
Rookie mistake
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.