Context
Node version: 6.13.1
Joi version: 13.3.0
Problem
Good day folks, I'm attempting to create a validation schema for an object that varies based on the value of one of its keys. When said key's value is set to certain string then some other keys are required. Here's a slightly contrived example:
const animalSchema = Joi.object()
.keys({
type: Joi.string().only(['MAMMAL', 'REPTILE']),
name: Joi.string()
})
.unknown(false)
.requiredKeys(['type', 'name']);
const reptileSchema = Joi.any()
.concat(animalSchema)
.keys({
coldBlooded: Joi.boolean().only(true),
laysEggs: Joi.boolean().only(true),
})
.requiredKeys(['coldBlooded', 'laysEggs']);
animalSchema.when(
'type',
{
is: 'REPTILE',
then: reptileSchema,
}
);
const input = {
type: 'REPTILE',
name: 'Snake'
};
const err = animalSchema.validate(input).error; // returns null but ValdiationError is expected as keys: ['coldBlooded', 'laysEggs'] should be required.
Would love if you guys can provide some insight on this. Thanks in advance.
Your choice, either as separate schemas:
const animalSchema = Joi.object()
.keys({
type: Joi.string().only(['MAMMAL', 'REPTILE']).required(),
name: Joi.string().required()
});
const reptileSchema = Joi.object()
.keys({
coldBlooded: Joi.boolean().only(true).required(),
laysEggs: Joi.boolean().only(true).required()
});
const schema = animalSchema
.when(
Joi.object({ type: 'REPTILE' }).unknown(),
{
then: reptileSchema
}
);
Or as a single schema:
const schema = Joi.object()
.keys({
type: Joi.string().only(['MAMMAL', 'REPTILE']).required(),
name: Joi.string().required(),
coldBlooded: Joi.when('type', { is: 'REPTILE', then: Joi.boolean().only(true).required(), otherwise: Joi.forbidden() }),
laysEggs: Joi.when('type', { is: 'REPTILE', then: Joi.boolean().only(true).required(), otherwise: Joi.forbidden() })
});
@Marsup Thanks, this helped a lot. I was able to get this to work for the use case I had in mind, however, there were a few things I noted:
Joi.object(...).unknown() as the condition instead of the combination of the property name and is. Anything to note here? I got this idea from the docs, did I misunderstand something?I don't understand the question, it's either a schema as condition, or is, not both.
Just to clarify, I wasn't able to get this to work:
const schema = animalSchema
.when(
'type',
{
is: 'REPTILE',
then: reptileSchema
}
);
So maybe there's something I'm missing regarding the use of is.
It's written in the readme that schemas are immutable, I should probably duplicate that info in the API.
Ah I see, I glossed over that section.
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
Your choice, either as separate schemas:
Or as a single schema: