class-validator
class-validator copied to clipboard
question: MinDate does not work correctly
Hi there, I got a problem when using MinDate validator https://stackblitz.com/edit/class-validator-boilerplate-gh437-xi3w3a?file=index.ts The problem: The validator return error minimum date allow in now, but my input is greater than now
@tony-dtravel Going through your Stackblitz snippet, I see you attempted to use the @IsISO8601 decorator alongside the @MinDate decorator. The use of @IsISO8601 implies that you expect a date string in ISO8601 format as input. The issue is that @MinDate accepts an argument of type Date whereas what is passed to it at runtime in your case is a string. A look at the validator implementation for MinDate reveals that validation will fail if the value of the decorated property is not an instance of Date. A solution might be to use the @Transform decorator from the class-transformer package to transform the date string into a date object. However, this is still a problem with @IsISO8601 and @IsDateString decorators as you get an error that the input received is not a valid ISO8601 date string because transformation occurs before decorators are applied. It took me some time to see that an issue with a PR attached is open, but it doesn't look like it'll be merged soon.
Solution? I suggest that you implement a custom decorator. You could keep the name of the decorator as MinDate so that when the feat: Make minDate and maxDate support specifying dynamic date PR gets merged/released, you only need to update your class-validator version and change your MinDate import path. Here's my implementation which makes a one-line change to the original implementation to allow MinDate receive a date string:
custom-min-date.decorator.ts
import { buildMessage, ValidateBy, ValidationOptions } from 'class-validator';
export const MIN_DATE = 'minDate';
/**
* Checks if the value is a date that's after the specified date.
*/
export function minDate(date: unknown, minDate: Date): boolean {
const dateObject: Date = typeof date === 'string' ? new Date(date) : <Date>date;
return dateObject instanceof Date && dateObject.getTime() >= minDate.getTime();
}
/**
* Checks if the value is a date that's after the specified date.
*/
export function MinDate(date: Date, validationOptions?: ValidationOptions): PropertyDecorator {
return ValidateBy(
{
name: MIN_DATE,
constraints: [date],
validator: {
validate: (value, args): boolean => minDate(value, args.constraints[0]),
defaultMessage: buildMessage(
(eachPrefix) => 'minimal allowed date for ' + eachPrefix + '$property is $constraint1',
validationOptions,
),
},
},
validationOptions,
);
}
The explanation by @firstCodeOutlaw is correct. Closing this as solved.
If the issue still persists, you may open a new Q&A in the discussions tab and someone from the community may be able to help.
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.