5
votes

I have a complex validation which changes depending on the a value in the JSON.

{ type: 'a', thing: 1, foo: 'abc' }
{ type: 'b', thing: 2, bar: 123 }

I want to validate that if the type is a, then use one set of siblings, if b then use another set of siblings

I would like to use the when switch, but cant work out how to do this at the root.

Joi.object({
  type: Joi.string().valid('a','b').required(),
  thing: Joi.number().required()
}).when('type', {
  switch: [
    { is: 'a', then: Joi.object({ foo: Joi.string() }) },
    { is: 'b', then: Joi.object({ bar: Joi.number() }) },
  ],
  otherwise: Joi.forbidden(),
});

However this gives the following error:

Error: Invalid reference exceeds the schema root: ref:type

This kinda makes sense as an error but I don't know how to restructure this to get it to apply the selector at the root.

Im using latest JOI (16.0.1)

1

1 Answers

8
votes

This can be resolved by prefixing the key name passed to .when() with a ., to denote the key as being relative to the object being validated:

Joi.object({
  type: Joi.string().valid('a','b').required(),
  thing: Joi.number().required()
})
.when('.type', {  /* <-- prefix with . */
  switch : [
    { is: 'a', then: Joi.object({ foo: Joi.string() }) },
    { is: 'b', then: Joi.object({ bar: Joi.number() }) },]
})

Here's a working example - hope that helps :-)