Open Ryanauger95 opened 4 years ago
Sorry for the slow response.
It looks like we haven't implemented it, sorry. I also see we haven't implemented alternatives
.
Hi, is there a way to perform when
with the current version? Is it possible via the any.custom() function?
My use case is to require one of two fields only. For example, I want to require email
when phone
is undefined, and vice versa.
@dsc-leo Great idea to use custom()
! I tried it out, and it works. 😁 That'll be a good workaround until joiful has the when()
decorator proper.
Below is the test I wrote to verify this. I wrapped the when()
in a convenience function. Note that one of the properties needs to use @lazy()
, otherwise there's a circular reference between properties which causes joi/hoek to error.
it('when(), via custom()', async () => {
function exclusiveOr<T>(schema: Joi.AnySchema, propertyName: keyof T & string) {
return schema.when(propertyName, {
is: Joi.required(), // Check if the "other" property is defined
then: Joi.forbidden(), // If so, the current schema "forbids" any value except undefined
otherwise: Joi.required(), // Otherwise, the current schema rejects undefined values
});
}
class ClassToValidate {
@string().custom(({ schema }: { schema: Joi.Schema }) => exclusiveOr<ClassToValidate>(schema, 'phone'))
public email?: string;
@lazy(({ joi}) => exclusiveOr<ClassToValidate>(joi.string(), 'email'))
public phone?: string;
constructor() {}
}
let instance = new ClassToValidate();
instance.email = 'foo@bar.com';
expect(instance).toBeValid();
instance = new ClassToValidate();
instance.phone = '555-5555';
expect(instance).toBeValid();
instance = new ClassToValidate();
instance.email = 'foo@bar.com';
instance.phone = '555-5555';
expect(instance).not.toBeValid();
instance = new ClassToValidate();
expect(instance).not.toBeValid();
});
I'll create a pr for this, if you didn't start working on it.
Is it possible to use the Joi "when" operator? In Joi, one can do:
Joi .string() .valid.apply(this, days) .required() .when("action", { is: "DELETE", then: Joi.string().optional(), otherwise: Joi.string().required() })
However, with jf,
@(jf .string() .valid.apply(this, days) .required() .when("action", { is: "DELETE", then: jf.string().optional(), otherwise: jf.string().required() }))
I receive an error: