Search code examples
node.jsjoi

How to access key outside of object in when condition of JOI?


How to put the condition for the outside field from the current object,

I have type field valid values are "text" and "video",

  • when type: "text" then text object is required of content object
  • when type: "video" then video object is required of content object
// not working
{
    type: Joi.string().valid("text", "video").required(),
    content: Joi.object().keys({
        text: Joi.object().keys({
            body: Joi.string().required(),
            preview_url: Joi.boolean().required()
        }).when('type', {
            is: "text",
            then: Joi.required(),
            otherwise: Joi.forbidden()
        }),

        video: Joi.object().keys({
            url: Joi.string().required()
        }).when('type', {
            is: "video",
            then: Joi.required(),
            otherwise: Joi.forbidden()
        })
    })
}

When I remove content object and put text and video object outside then it works perfectly, as the below code is working,

// working
{
    type: Joi.string().valid("text", "video").required(),
    text: Joi.object().keys({
        body: Joi.string().required(),
        preview_url: Joi.boolean().required()
    }).when('type', {
        is: "text",
        then: Joi.required(),
        otherwise: Joi.forbidden()
    }),

    video: Joi.object().keys({
        url: Joi.string().required()
    }).when('type', {
        is: "video",
        then: Joi.required(),
        otherwise: Joi.forbidden()
    })
}

Solution

  • I found the solution from this reference git issue's solution issue-799,

    Just need to put when condition for content object,

    {
        type: Joi.string().valid("text", "video").required(),
        content: Joi.object().keys({
            text: Joi.object().keys({
                body: Joi.string().required(),
                preview_url: Joi.boolean().required()
            }).forbidden(),
            video: Joi.object().keys({
                url: Joi.string().required()
            }).forbidden()
        }).required()
        .when('type', {
            is: "text",
            then: Joi.object({ text: Joi.required() })
        })
        .when('type', {
            is: "video",
            then: Joi.object({ video: Joi.required() })
        })
    }