I have a complex condition where I need to use "when" inside a "when". I am getting the error
"Cannot merge type boolean with another type: alternatives"
Describe your issue here, include schemas and inputs you are validating if needed.
const schema = Joi.object().keys({
a: Joi.boolean(),
b: Joi.string(),
c: AnotherJoiObject.when("a", {"is": true, "then": Joi.optional(), "otherwise": Joi.forbidden()}),
d: Joi.boolean()
});
const AnotherJoiObject = Joi.object().keys({
object1: childJoiObject1,
object2: childJoiObject2
})
.when("b", {"is": "something", "then": Joi.object({
object1: Joi.optional().when("d",{
"is": true,
"then": Joi.object({
"prop1": Joi.required()
})
}),
object2: Joi.forbidden()
}),
"otherwise": Joi.object({
object2: Joi.optional(),
object1: Joi.forbidden()
})
});
As can be seen, "c" is another joi object, which is dependent upon "a". And again, c.object1 and c.object2 are dependent upon "b". And "c.object1.prop1" is dependent on "d". I am getting the error "Cannot merge type boolean with another type: alternatives"
I need to get "c.object1.prop1" to be required or optional when "d" is true/false.
what are the definitions of childJoiObject1 and childJoiObject2?
I think the errors you're getting are related to having object1 defined in object().keys() and in the alternatives definition.
This is something I looked into a while ago, I'd say it's a bug/enhancement but it'll take time. The problem is he's trying to merge an object with an alternative containing objects, in theory it should work, but the current concat algorithm doesn't deal with that. Feel free to take that one if you love hard problems.
The solution to this would be that your topmost validation should always start with Joi.when() and not AnotherJoiObject
@avparmar1805 see my example below:
// ...
// ...
'animal': Joi
.when('legs', {
is: 2,
then: Joi
.when('species', {
is: 'mammal',
then: Joi.string().valid('human').valid('kangaroo').required()
})
.when('species', {
is: 'bird',
then: Joi.string().valid('eagle').valid('toucan').required()
})
})
// ...
// ...
This will prevent the "Cannot merge type boolean with another type: alternatives" error.
@avparmar1805
For your code, try doing this instead:
const AnotherJoiObject = Joi.object().keys({
object1: childJoiObject1,
object2: childJoiObject2
})
.when("b", {"is": "something", "then": Joi.object({
object1: Joi.optional().when("d",{
"is": true,
"then": Joi.object({
"prop1": Joi.required()
})
}),
object2: Joi.forbidden()
}),
"otherwise": Joi.object({
object2: Joi.optional(),
object1: Joi.forbidden()
})
});
const schema = Joi.object().keys({
a: Joi.boolean(),
b: Joi.string(),
c: Joi.when("a", {"is": true, "then": AnotherJoiObject.optional(), "otherwise": Joi.forbidden()}),
d: Joi.boolean()
});
Maybe we can mark this as resolved?
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
The solution to this would be that your topmost validation should always start with
Joi.when()and notAnotherJoiObject@avparmar1805 see my example below:
This will prevent the
"Cannot merge type boolean with another type: alternatives"error.