Search code examples
javascriptjoi

Joi nested when


const schema = {
    a: Joi.any(),
    b: Joi
      .boolean()
      .default(false),
    c: Joi
      .boolean()
      .default(false)
}

How can I fix the abovementioned Joi schema to matches the following rules

  • One of b or c can be true at the same time
  • When b or c is true, a is forbidden otherwise a is required

Solution

  • Joi.object( {
      a: Joi
          .boolean()
          .default(false),
      b: Joi
          .boolean()
          .default(false),
      c: Joi.string().when(
        'a', {
          is: false,
          then: Joi.when(
            'b', {
              is: false,
              then: Joi.string().required()
            }
          )
        }
      ),
    })
    

    I tried nested when before asking question, but it not working before because of the order of rules

    Joi.object( {
      c: Joi.string().when(
        'a', {
          is: false,
          then: Joi.when(
            'b', {
              is: false,
              then: Joi.string().required()
            }
          )
        }
      ),
      a: Joi
          .boolean()
          .default(false),
      b: Joi
          .boolean()
          .default(false),
    })
    

    the default value in the second schema is not set when the when is checking, So If you validate an empty object {}, the first schema has Validation Error: "c" is required error while the second Passed with {a: false, b: false}

    I opened an issue here https://github.com/sideway/joi/issues/2683