Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ReferenceError: cannot access [*] before initialization. Validating nested objects with Class-validator in NestJs

I can't seem to understand what is going on here, or what i'm doing wrong, I've read other threads with similar issues, but didn't find one like mine (people are always asking about validating typed Arrays)

Here goes the class i want to validate.


export class CreateActivityDto {
   
    //other un-problematic validated properties

    @IsArray()
    @ValidateNested({ each: true })
    @Type(() => Plan)  
    plan: Plan[]  //this one works fine
    

    @IsObject()
    @IsDefined()
    @Type(() => Location) //imported from class-transformer
    location: Location
}
class Location {
    @IsString()
    @IsNotEmpty()
    address: string
    @IsObject()
    @Type(() => LatLng) //imported from class-transformer
    coords: LatLng
}

class LatLng {
    @IsNumber()
    lng: number
    @IsNumber()
    lat: number
}

Weirdly enough, if i declare location as an array of location (location: Location[]) it doesn't throw the error

This is being thrown in RunTime, few miliseconds after the server tries to bootstrap

[6:25:19 pm] Found 0 errors. Watching for file changes.

[fullDirHere]\src\activity\dtos\activity.dto.ts:52
location: Location
              ^
ReferenceError: Cannot access 'Location' before initialization

and this is my main.ts file

async function bootstrap() {
  const app = await NestFactory.create(AppModule, { cors: true });
  app.useGlobalPipes(new ValidationPipe({
    whitelist: true,
    transform: true,
    transformOptions: {
      enableImplicitConversion: true
    }
  }))
  await app.listen(3000);
}
bootstrap();

In case there's any doubts, this an example of a valid object i could receive

{
"location": {
          "address": "Av. Corrientes 2003, Buenos Aires, Argentina",
          "coords": {
                    "lat": -34.6042967,
                    "lng": -58.39546360000001
               },
...other props,
}
like image 610
Marco Di Loreto Avatar asked Jun 02 '26 14:06

Marco Di Loreto


1 Answers

If you change the order of declaration of these classes, it should work fine. I tested this on my local also:


class LatLng {
    @IsNumber()
    lng: number;
    @IsNumber()
    lat: number;
}

class Location {
    @IsString()
    @IsNotEmpty()
    address: string;
    @IsObject()
    @Type(() => LatLng) //imported from class-transformer
    coords: LatLng;
}
export class CreateActivityDto {
    //other un-problematic validated properties

    @IsArray()
    @ValidateNested({ each: true })
    @Type(() => Plan)  
    plan: Plan[]  //this one works fine

    @IsObject()
    @IsDefined()
    @Type(() => Location) //imported from class-transformer
    location: Location;
}

As you might know, the decorators are usually run before other piece of code.

like image 125
Yehya Avatar answered Jun 06 '26 07:06

Yehya



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!