Search code examples
typescriptnestjsclass-validator

Nestjs class-validator nested object validation failure


This is my model structure

import { Type } from "class-transformer"
import { IsObject, IsOptional, IsString, MaxLength, ValidateNested } from "class-validator"

export class DestinationRequest {
  @IsString()
  @MaxLength(2, { message: 'should be only of 2 letters' })
  lang: string

  @IsString()
  @MaxLength(50, { message: 'should be only of 50 letters' })
  name: string

  @IsOptional()
  @ValidateNested()
  @IsObject()
  @Type(() => AddressRequest)
  address: AddressRequest

  @IsString()
  @IsOptional()
  content: string
}


export class AddressRequest {
  @IsString()
  @MaxLength(50, { message: 'city should be only 50 letters' })
  city: string

  @IsString()
  @MaxLength(25, { message: 'country should be only 25 letters' })
  country: string

  @IsString()
  @IsOptional()
  @MaxLength(100, { message: 'detail should be only 100 letters' })
  detail: string

  @IsOptional()
  geolocation: {
    latitude: number,
    logitude: number
  }
}

When I run the app, the app fails to start with the following error

ReferenceError: Cannot access 'AddressRequest' before initialization at Object. (/destination.models.ts:17:12) at Module._compile (internal/modules/cjs/loader.js:1085:14) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10) at Module.load (internal/modules/cjs/loader.js:950:32) at Function.Module._load (internal/modules/cjs/loader.js:790:12) at Module.require (internal/modules/cjs/loader.js:974:19) at require (internal/modules/cjs/helpers.js:101:18) at Object. () at Module._compile (internal/modules/cjs/loader.js:1085:14) at Object.Module._extensions..js (internal/modules/cjs/loader.js:1114:10)


Solution

  • The error is because the AddressRequest class has to be declared before DestinationRequest.

    This fixed it for me

    import { Type } from 'class-transformer';
    import {
      IsObject,
      IsOptional,
      IsString,
      MaxLength,
      ValidateNested,
    } from 'class-validator';
    
    export class AddressRequest {
      @IsString()
      @MaxLength(50, { message: 'city should be only 50 letters' })
      city: string;
    
      @IsString()
      @MaxLength(25, { message: 'country should be only 25 letters' })
      country: string;
    
      @IsString()
      @IsOptional()
      @MaxLength(100, { message: 'detail should be only 100 letters' })
      detail: string;
    
      @IsOptional()
      geolocation: {
        latitude: number;
        logitude: number;
      };
    }
    
    export class DestinationRequest {
      @IsString()
      @MaxLength(2, { message: 'should be only of 2 letters' })
      lang: string;
    
      @IsString()
      @MaxLength(50, { message: 'should be only of 50 letters' })
      name: string;
    
      @IsOptional()
      @ValidateNested()
      @IsObject()
      @Type(() => AddressRequest)
      address: AddressRequest;
    
      @IsString()
      @IsOptional()
      content: string;
    }