Jose Gaspar
Jose Gaspar

Reputation: 41

@MaxDate from class-validator not working as expected with Nestjs

I don't have a lot of experience developing with Nodejs/Nestjs. I'm developing a REST API where one of endpoints receives a User body with a birthday property.

I want to validate that date of birth is always before the current day. This is a snippet of my code:

import { IsString, IsDateString, MaxDate } from 'class-validator';

export class CreateUserDto {
  @IsString()
  readonly username: string;

  @IsDateString()
  @MaxDate(new Date())
  readonly dateofbirth: Date;
}

And this is my entity:

import { Entity, Column, PrimaryColumn } from 'typeorm';

@Entity()
export class User {
  @PrimaryColumn()
  username: string;

  @Column()
  dateofbirth: Date;
}

However, when making a POST request I always get the same error and can't understand why: {"statusCode":400,"message":["maximal allowed date for dateofbirth is Mon Nov 01 2021 12:20:11 GMT+0000 (Western European Standard Time)"],"error":"Bad Request"}

Thank you for your help and time.

Upvotes: 3

Views: 4177

Answers (4)

Ben Brahim Jamil
Ben Brahim Jamil

Reputation: 85

This is how you can work with the @MinDate and @MaxDate You should use the @Transform to transform the date format

 @IsDate()
 @Transform( ({ value }) => new Date(value))
 @MinDate(new Date())
 dateOfBirth: Date;

Like this your code should work fine

Upvotes: 0

Pedram
Pedram

Reputation: 1843

TL;DR

  1. Cast the string to Date with the Type decorator:
@Type( () => Date )
  1. Replace @MaxDate(new Date()) with @MaxDate(() => new Date())

Explanation

  • Using @Type( () => Date ) transforms whatever given to a Date object
  • Using @MaxDate(new Date()) creates a static date when the service is ran as Simon mentioned here. As a workaround, you can delay this instance creation to when the DTO runs with specifying the MaxDate argument as an arrow function: @MaxDate( () => new Date())

Partial code:

@ApiProperty({ 
   type: 'string', 
   format: 'date',
   example: new Date(1986, 11, 11) 
})
@Type( () => Date ) // cast to Date type
@MaxDate(() => new Date(), {
    message: () => 
        `maximal allowed date for date of birth is ${new Date().toDateString()}`,
  })
dateOfBirth: Date;

Upvotes: 3

Simon Hansen
Simon Hansen

Reputation: 700

The date passed into the Validator MaxDate is stored once when the service is started. So MaxDate is now comparing the date when the service started with the given date.

I did not find a solution to use the MaxDate Decorator with the current time. At the end we compare the sent date with current time in the controller function (the old/classic way).

Upvotes: 0

Jose Gaspar
Jose Gaspar

Reputation: 41

I solved the problem when added @Type(() => Date) to dateofbirth from class-transformer

Upvotes: 1

Related Questions