Search code examples
javascriptnode.jstypescriptnestjsdto

Unable to validate nested dto class in another class in nest js


I am trying to access 2 classes in one dto class but when I check the schema in swagger, it shows only string instead of complete schema. I have gone through a lot of stackoverflow posts but i couldn't find any issue with my dto schema. Please help me in correcting the dto.

This is the schema visible in swagger

{
  "originDestinations": [
    "string"
  ],
  "travelers": [
    "string"
  ]
}

This is what I want.

{
    "originDestinations": [
        {
            "originLocationCode": "string",
            "destinationLocationCode": "string",
            "departureDate": "string"
        }

    ],
    "travelers": [
        {
            "travelerType": "string",
            "fareOptions": [
                "string"
            ]
        }
        
    ]   
  }

When I am running it in postman I am getting an error response where I am getting validations in message.

This is my dto


import { ApiProperty, ApiPropertyOptional } from "@nestjs/swagger";
import { Type } from "class-transformer";
import { IsNotEmpty, IsArray, ValidateNested, IsDateString, MinLength, MaxLength, } from "class-validator";





class Travelers{
    
    @ApiProperty({ enum: [ "ADULT", "CHILD", "SENIOR", "YOUNG", "HELD_INFANT", "SEATED_INFANT", "STUDENT" ]})
    travelerType:string;
    
    @ApiProperty({ enum: [ "STANDARD", "INCLUSIVE_TOUR", "SPANISH_MELILLA_RESIDENT", "SPANISH_CEUTA_RESIDENT", "SPANISH_CANARY_RESIDENT", "SPANISH_BALEARIC_RESIDENT", "AIR_FRANCE_METROPOLITAN_DISCOUNT_PASS", "AIR_FRANCE_DOM_DISCOUNT_PASS", "AIR_FRANCE_COMBINED_DISCOUNT_PASS", "AIR_FRANCE_FAMILY", "ADULT_WITH_COMPANION", "COMPANION" ]})
    fareOptions: string[];


} 

class OriginDestinations {


    @ApiProperty()
    @IsNotEmpty()
    @MinLength(3)
    @MaxLength(3)
    originLocationCode:string;

    @ApiProperty()
    @IsNotEmpty()
    @MinLength(3)
    @MaxLength(3)
    destinationLocationCode:string;

    @ApiProperty()
    @IsDateString()
    @IsNotEmpty()
    departureDate:string;


    // @ApiProperty()
    // @IsNotEmpty()
    // adults:string;


}

export class originDestinationsDto{
    @IsArray()
    @ApiProperty()
    @IsNotEmpty()
    @ValidateNested({ each: true })
    @Type(() => OriginDestinations)
    originDestinations:OriginDestinations[];

    @ApiProperty()
    @IsArray()
    @IsNotEmpty()
    @ValidateNested({ each: true })
    @Type(() => Travelers)
    travelers:Travelers[];

}

If I try to hit it with postman this is the response generate there

{
    "statusCode": 400,
    "message": [
        "originLocationCode must be shorter than or equal to 3 characters",
        "originLocationCode must be longer than or equal to 3 characters",
        "originLocationCode should not be empty",
        "destinationLocationCode must be shorter than or equal to 3 characters",
        "destinationLocationCode must be longer than or equal to 3 characters",
        "destinationLocationCode should not be empty",
        "departureDate should not be empty",
        "departureDate must be a valid ISO 8601 date string"
    ],
    "error": "Bad Request"
}

Solution

  • Swagger cant automatically recognise, your params as objects, so you need to specify it by setting type param:

    export class originDestinationsDto{
        @ApiProperty({ type: [OriginDestinations] })
        originDestinations:OriginDestinations[];
    
        @ApiProperty({ type: [Travelers] })
        travelers:Travelers[];
    
    }
    

    take a note, for array, type should be array with specific DTO { type: [Travelers] } while for single object it should be { type: Travelers }