Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"when" operator? #113

Open
Ryanauger95 opened this issue Mar 3, 2020 · 4 comments
Open

"when" operator? #113

Ryanauger95 opened this issue Mar 3, 2020 · 4 comments

Comments

@Ryanauger95
Copy link

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:

TypeError: jf.string(...).valid.apply(...).required(...).when is not a function

@laurence-myers
Copy link
Member

Sorry for the slow response.

It looks like we haven't implemented it, sorry. I also see we haven't implemented alternatives.

@dsc-leo
Copy link

dsc-leo commented Jul 9, 2020

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.

@laurence-myers
Copy link
Member

@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();
    });

@sshbio
Copy link

sshbio commented Nov 1, 2020

I'll create a pr for this, if you didn't start working on it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants