Search code examples
node.jsvalidationnpmjoi

Using Joi, how do I set a rule that states: if prop A is present, then prop b or C or D must be present?


Using Joi, how can I require that, if a property is present then one of three different properties must also be present?

For example:

Take object obj:

const obj = {
    a: true,
    b: undefined, 
    c: true
    d: undefined
}

I can write:

const validate = (obj) =>{
    if(obj.a && (obj.b || obj.c || obj.d)){
        return true
    }
}

This way if I receive:

    const o1 = {
        a: true,
        b: undefined, 
        c: true,
        d: undefined
    }
    const o2 = {
        a: true,
        b: undefined, 
        c: undefined,
        d: undefined
    }
    const 03 {
        a: undefined,
        b: true, 
        c: undefined,
        d: undefined
    }
validate(o1)//true
validate(o2)//false
validate(03)//false

How do I accomplish this using Joi? I am able to enforce dependencies between two properties using the .when() method (see below); however, I am unsure how to accomplish the above. Is it even possible?

//from documentation
const schema = {
    a: Joi.valid('a', 'b', 'other'),
    other: Joi.string()
        .when('a', { is: 'other', then: Joi.required() }),
};

Hope to find an answer, as this is stumping me.


Solution

  • // If a === true, then b, c or d should be present
    Joi.object({
      a: Joi.boolean(),
      b: Joi.boolean(),
      c: Joi.boolean(),
      d: Joi.boolean(),
    }).when(".a", { is: true, then: Joi.object().or("b", "c", "d") });
    
    // Validation Error: "value" must contain at least one of [b, c, d]
    const invalidData = {
      a: true,
      b: undefined,
      c: undefined,
      d: undefined,
    };
    
    // Validation Passed
    const validData = {
      a: true,
      b: undefined,
      c: true,
      d: undefined,
    };
    

    It works because the when allows to transform the object and add the or

    You cant test here