Let there be:
const a = {
b: Joi.alternatives().conditional("a", {
is: "c",
then: Joi.any(),
otherwise: Joi.string().valid("d", "e").required(),
}),
a: Joi.string().valid(
"a",
"b",
"c",
),
c: Joi.bool(),
};
const b = {
foo: Joi.alternatives().conditional("c", {
is: true,
then: Joi.any(),
otherwise: Joi.alternatives().conditional("a", {
switch: ["a", "b"].map((a, i) => ({
is: a,
then: Joi.alternatives().conditional("b", {
switch: ["d"].map((b, i) => ({
is: b,
then: Joi.string().required(),
...(i === ["d"].length - 1 && { otherwise: Joi.any() }),
})),
}),
...(i === ["a", "b"].length - 1 && {
otherwise: Joi.any(),
}),
})),
}),
}),
};
Validating the following data:
{
"a": "a",
"b": "d",
"c": "true"
}
When using:
Joi.object({
...a,
...b,
});
Validation Passed
But when using:
Joi.object({
...b,
...a,
});
Validation Error: "foo" is required
Why does order of ...a
and ...b
matter here?
Let:
const a = {
b: Joi.any().when("a", {
is: "c",
then: Joi.any(),
otherwise: Joi.string().valid("d", "e").required(),
}),
a: Joi.string().valid("a", "b", "c"),
c: Joi.bool(),
};
const b = {
foo: Joi.any().when("c", {
is: true,
then: Joi.any(),
otherwise: Joi.any().when("a", {
switch: ["a", "b"].map((a, i) => ({
is: a,
then: Joi.any().when("b", {
switch: ["d"].map((b, i) => ({
is: b,
then: Joi.string().required(),
...(i === ["d"].length - 1 && { otherwise: Joi.any() }),
})),
}),
...(i === ["a", "b"].length - 1 && {
otherwise: Joi.any(),
}),
})),
}),
}),
};
Whether using ...a
first or ...b
first
Validation Passed
Why does order of ...a
and ...b
not matter here?
Note that alternatives.conditional() is different than any.when(). When you use any.when() you end up with composite schema of all the matching conditions while alternatives.conditional() will use the first matching schema, ignoring other conditional statements.
– Norven