serge1peshcoff
serge1peshcoff

Reputation: 4670

How to compare the custom validation type with itself in Joi?

I need to validate the object with Joi that has two keys, start and end, which are date strings in YYYY-MM-DD formats.

The validation rules I need for this object is:

Joi doesn't provide the custom validations for date comparison without time, so I needed to extend it, here is my solution:

const date = Joi.extend({
    base: Joi.string(),
    name: 'string',
    language: {
        isValidDate: 'is not a valid date'
    },
    rules: [{
        name: 'isValidDate',
        validate(params, value, state, options) {
            if (!moment(value, 'YYYY-MM-DD', true).isValid()) {
                return this.createError('date.isValidDate', { v: value }, state, options);
            }

            return value;
        }
    }, {
        name: 'isDateAfter',
        params: {
            another: Joi.string().required() // This is where I'm stuck
        },
        validate(params, value, state, options) {
            if (!moment(value, 'YYYY-MM-DD', true).isAfter(params.another, 'day')) {
                return this.createError('date.isValidDate', { v: value }, state, options);
            }

            return value;
        }
    }]
});

My schema is described like that:

Joi.object({
    start: datetime.string().isValidDate(),
    end: datetime.string().isValidDate()
        .isDateAfter(Joi.ref('start', { default: '0000-00-00' }))
}).optional()

If I run this, I'll get an error:

ValidationError: {
  "another" [1]: "[ref:start]"
}

[1] "another" must be a string

103 |                     start: datetime.string().isValidDate(),
104 |                     end: datetime.string().isValidDate()
> 105 |                         .isDateAfter(Joi.ref('start', { default: '0000-00-00' }))
106 |                 }).optional()

How can I compare the 'end' key with the 'start' key if they are the same type?

Upvotes: 0

Views: 1137

Answers (1)

serge1peshcoff
serge1peshcoff

Reputation: 4670

Answering my own question:

I've found that there's an extension to compare date, from the maintainers of Joi itself, called joi-date-extensions. So I can easily compare dates without custom validations, like that:

date: Joi.object({
    start: Joi.date().format('YYYY-MM-DD'),
    end: Joi.date().format('YYYY-MM-DD').min(Joi.ref('start', { default: '0000-00-00' }))
}).optional()

Upvotes: 0

Related Questions