I have this Joi schema:
let schema = {};
let stations = {
contact: {
first_name: Joi.string().min(2).max(10).regex(Regex.alphabeta, 'alphabeta').allow("").error(JoiCustomErrors),
last_name: Joi.string().min(2).max(10).regex(Regex.alphabeta, 'alphabeta').allow("").error(JoiCustomErrors),
phone: Joi.string().min(10).max(10).regex(Regex.num, 'num').allow("").error(JoiCustomErrors),
},
address: {
place: Joi.string().min(2).max(10).regex(Regex.alphanum, 'alphanum').required().error(JoiCustomErrors),
city: Joi.string().min(2).max(30).required().error(JoiCustomErrors),
street: Joi.string().min(2).max(30).regex(Regex.alphabeta, 'alphabeta').required().error(JoiCustomErrors),
house_number: Joi.string().min(1).max(6).regex(Regex.alphanum, 'alphanum').allow("").error(JoiCustomErrors)
},
passengers_amount: Joi.number().min(0).max(4).required().error(JoiCustomErrors),
notes: Joi.string().min(2).max(100).regex(Regex.alphanum, 'alphanum').allow("").error(JoiCustomErrors)
};
schema.stations = Joi.array().items(stations).min(1).max(5).required().error(JoiCustomErrors);
As you can see, schema.stations
is an array of min 1 and max 5 elements.
I want that each of the elements will have the field of "address.place" only if the "contact.first_name" AND "contact.last_name" AND "contact.phone"
exists (or filled properly based on the schema).
How can I do that?
You can to use Joi.when()
and create a schema like this:
Joi.object().keys({
contact: Joi.object().keys({
first_name: Joi.string(),
last_name: Joi.string(),
phone: Joi.string(),
}),
address: Joi.object().keys({
place: Joi.string(),
city: Joi.string().min(2).max(30),
street: Joi.string(),
house_number: Joi.string()
}).when('contact', {
is: Joi.object().keys({
first_name: Joi.exist(),
last_name: Joi.exist(),
phone: Joi.exist(),
}),
then: Joi.object({ place: Joi.required() }).required(),
otherwise: Joi.object({ place: Joi.forbidden() })
}),
passengers_amount: Joi.number(),
notes: Joi.string()
});
I just simplified your shema so it's easy to understand.
Basically, what we are saying here is, if contact.first_name, contact.last_name and contact.phone exists, then address and address.place are required, otherwise address.place is forbidden.
For instance, this object will fail, because address does not exist:
{
address: {
first_name: 'a',
last_name: 'b',
phone: 'c'
}
}
and this will fail because address.place does not exist:
{
address: {
first_name: 'a',
last_name: 'b',
phone: 'c'
},
contact: {
}
}
Finally, according with the schema defined, this object will pass:
{
address: {
first_name: 'a',
last_name: 'b',
phone: 'c'
},
contact: {
place: 'd'
}
};