Joi nested schemas and default values

2.4k views Asked by At

I'm trying to get Joi to enforce default values on a secondary schema referenced by another. I have two schemas like so:

const schemaA = Joi.object().keys({
  title: Joi.string().default(''),
  time: Joi.number().min(1).default(5000)
})

const schemaB = Joi.object().keys({
  enabled: Joi.bool().default(false),
  a: schemaA
})

What I want is to provide an object where a is not defined and have Joi apply the default values for it instead like this:

const input = {enabled: true}

const {value} = schemaB.validate(input)

//Expect value to equal this:
const expected = {
  enabled: true,
  a: {
    title: '',
    time: 5000
  }
}

The problem is that since the key is optional it is simply not enforced. So what I want is for it to be optional yet properly filled with schemaA defaults if not present. I've been looking through the documentation, but can't seem to find any info on this though I'm probably missing something obvious. Any tips?

2

There are 2 answers

2
Vikash Rathee On BEST ANSWER

Update : April, 2020.

Now, you can use default() in nested objects. Here is the commit in repo with test.

var schema = Joi.object({
                a: Joi.number().default(42),
                b: Joi.object({
                    c: Joi.boolean().default(true),
                    d: Joi.string()
                }).default()
            }).default();
0
nerdlinger On

This should do it:

const schemaA = Joi.object().keys({
  title: Joi.string().default(''),
  time: Joi.number().min(1).default(5000),
});

const schemaB = Joi.object().keys({
  enabled: Joi.bool().default(false),
  a: schemaA.default(schemaA.validate({}).value),
});

Although it would be much better if they would implement a feature to let us pass in Joi schema objects for defaults, like so: schemaA.default(schemaA) or schemaA.default('object')