I want to specify required() before anything else, as this is the most common trait in my schemas and it reads as more natural English compared to the reverse.
joi.required().string()
joi.required().string();
^
TypeError: joi.required(...).string is not a function
at Object.<anonymous> (/Users/sholladay/Code/noirdoor/noirdoor/lib/route/foo.js:5:16)
at Module._compile (module.js:569:30)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:503:32)
at tryModuleLoad (module.js:466:12)
at Function.Module._load (module.js:458:3)
at Function.Module.runMain (module.js:605:10)
at startup (bootstrap_node.js:158:16)
at bootstrap_node.js:575:3
For the schema to be successfully constructed with the same semantics as joi.string().required().
I'm not saying whether this is the desired behavior, but at least here is why this is happening:
When you do Joi.required() the type of the schema defaults to any. So it is the equivalent of writing Joi.any().required().
So when you do Joi.required().string() it is the equivalent of writing Joi.any().required().string(). Only the base Joi object has the additional type methods. Once you return an instance of a schema with a type, you lose the methods on the base Joi object that correspond to other types.
Not readable, but just throwing it out there, this works:
const schema = Joi.required().concat(Joi.string());
schema.describe();
/*
{
type: 'string',
flags: { presence: 'required' },
invalids: [ '' ]
}
*/
Highly unlikely to happen. If you find yourself having most things required, consider using the presence setting.
consider using the presence setting
I would prefer something on the schema, but I can live with that.
How would one do this with hapi, given that it is responsible for calling validate() for us? The closest thing I found looks like it is set on a connection object, but I can't tell if that is correct (it is three years old) or if there are any alternatives whose effects are more local..
You can set the presence option on your schema itself:
Joi.object().keys({
prop1: Joi.string()
}).options({ presence: 'required' })
Good enough for me. Thanks, @WesTyler. :)
Most helpful comment
You can set the presence option on your schema itself: