Reputation: 4670
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:
isValidDate
)end
should be the date after the start
(if both end
and start
are provided)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
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