class-validator icon indicating copy to clipboard operation
class-validator copied to clipboard

question: MinDate does not work correctly

Open tony-dtravel opened this issue 3 years ago • 1 comments

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 avatar Jul 20 '22 10:07 tony-dtravel

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

firstCodeOutlaw avatar Sep 10 '22 00:09 firstCodeOutlaw

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.

NoNameProvided avatar Nov 13 '22 14:11 NoNameProvided

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.

github-actions[bot] avatar Dec 14 '22 00:12 github-actions[bot]