Raz Buchnik
Raz Buchnik

Reputation: 8411

Joi how to merge/append/add sub schemas depends on specific inputs

I want to make a user input validation in Node.js REST api.

I have this schema for example:

let schema = Joi.object().keys({
    client: {
      type: Joi.string().valid(["private", "business"]).required().error(JoiCustomErrors)
    },
 });

Now if the user fills the form with type as private, I want to add a to the schema, so it will be looking something like this:

let schema = Joi.object().keys({
    client: {
      type: Joi.string().valid(["private", "business"]).required().error(JoiCustomErrors),
      a: Joi.string().required().error(JoiCustomErrors)
    },
  });

If the user fills business in the type field I want to append b instead of a (some options for the example).

I have tried:

let b = Joi.string().required().error(JoiCustomErrors);

schema.client.append({b: b}); // 1
schema.client.append(b); // 2
schema.client.b = b; // 3

But nothing works I receive an undefined error: TypeError: Cannot read property 'append' of undefined

Upvotes: 0

Views: 2385

Answers (1)

Ankh
Ankh

Reputation: 5728

The trick here is to define both rules for a and b in the same schema and add conditional requirements on whether they're required or not.

Take a look at the following:

Joi.object().keys({
    client: Joi.object().keys({
        type: Joi.string().valid([ 'private', 'business' ]).required(),
        a: Joi.string().when('type', { is: 'private', then: Joi.required() }),
        b: Joi.string().when('type', { is: 'business', then: Joi.required() })
    }).nand('a', 'b')
});

This schema makes client.type required as you already have it. a and b have been defined as optional strings but they make use of Joi's .when() function to create a conditional requirement based on the value of type.

If type is 'private', a is required; if it's 'business', b is required.

I've also added a .nand() modifier to the client object which will forbid a and b to exist at the same time.

Upvotes: 1

Related Questions