I did some digging on the docs, SO and source and didn't find anything about this, but I can be wrong.
What I need to do is only validate some keys when an external condition is met. Different from what we have today, that the condition is based on the object that is being validated.
//buildUserSchema.js
export default ({ ageIsRequired }) => {
const userSchemaKeys = {
name: Joi.string().min(2).required().label('Name'),
lastName: Joi.string().min(3).required().label('Last name'),
};
if (ageIsRequired) {
userSchemaKeys.age = Joi.number().positive().required().label('Age');
}
return Joi.object(userSchemaKeys);
}
This is an oversimplified example, I could have several xxxIsRequired to check.
Maybe we could do some like:
//buildUserSchema.js
export default ({ ageIsRequired }) => Joi.object({
name: Joi.string().min(2).required().label('Name'),
lastName: Joi.string().min(3).required().label('Last name'),
age: Joi.number().positive().label('Age').required(ageIsRequired) //or .required(() => ageIsRequired)
});
The thing is if ageIsRequired then I must validate it, otherwise I need to completely ignore the key.
Thanks in advance.
Yes.
Have you looked into using the context refs described here?
something like
const schema = Joi.object().keys({
conditional: Joi.number().when('$condition', {
is: Joi.boolean().valid(true).required(),
then: Joi.required(),
otherwise: Joi.optional()
})
});
schema.validate({}); // error: null
schema.validate({}, {context: {condition: false}}); // error: null
schema.validate({}, {context: {condition: true}}); // ValidationError: child "conditional" fails because ["conditional" is required]
The benefit of using the validation context instead of your proposal is that the validation context can pull the value at validation time, whereas I believe doing it in the schema composition would effectively freeze the require value based on the external variable's value at schema compile time.
Hey @WesTyler, thanks for the response!
Yeah, I believe this could help me, for me this wasn't clear, about the possibility to use those context values with the .when.
I'll need to change some stuff to be able to use this approach since the schema.validate is being called by another part of the application.
I'm going to close this.
Thanks for your help!
Just wondering, why don't you just define 2 schemas like so?
const schema = Joi.object({
name: Joi.string().min(2).required().label('Name'),
lastName: Joi.string().min(3).required().label('Last name'),
});
const schemaWithAge = schema.keys({
age: Joi.number().positive().required().label('Age')
})
export default ({ ageIsRequired }) => {
return ageIsRequired ? schemaWithAge : schema;
}
As I said, I oversimplified the example.
In reality, I can have this isRequired check for virtually any key (except id and some other exceptions).
Then would a simple schema with a call to requiredKeys work?
This is also an option, but then I would need to create an array based on my requirements, it's almost what I had, in my first question.
I believe I'm going with the approach mentioned by @WesTyler for now.
Just changed everything here, and it seems to be a valid option for me.
Thanks!
This thread has been automatically locked due to inactivity. Please open a new issue for related bugs or questions following the new issue template instructions.
Most helpful comment
This is also an option, but then I would need to create an array based on my requirements, it's almost what I had, in my first question.
I believe I'm going with the approach mentioned by @WesTyler for now.
Just changed everything here, and it seems to be a valid option for me.
Thanks!