Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: cannot read property 'name' of undefined #803

Open
inmativ opened this issue Jul 2, 2021 · 4 comments · May be fixed by #1118
Open

fix: cannot read property 'name' of undefined #803

inmativ opened this issue Jul 2, 2021 · 4 comments · May be fixed by #1118
Labels
status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature.

Comments

@inmativ
Copy link

inmativ commented Jul 2, 2021

This is my first issue. Please be friendly. Pardon my bad english.

Description

I am writing a project in NestJS. An error occurs when validating an array with objects of different types.
The error is reproduced only if you refer to the route using Postman. If you just call validate (new Facts (...)), everything works as expected. I tried on versions 0.3.1 and 0.4.0.

Discriminator parameters

  @ArrayNotEmpty()
  @ValidateNested()
  @Type(() => FactDTO, {
    discriminator: {
      property: 'eventTypeCode',
      subTypes: [
        { value: FlightExecutionFactDTO, name: '1' },
        { value: FlightFinishFactDTO, name: '2' },
      ],
    },
    keepDiscriminatorProperty: true,
  })
  facts: (FlightExecutionFactDTO | FlightFinishFactDTO)[];
}

Parent class decorators

export class FactDTO {
  @ApiProperty()
  @IsRFC3339()
  moment: string;

  @ApiProperty()
  @IsEnum(EventTypeCode)
  eventTypeCode: EventTypeCode;

  @IsNotEmptyObject()
  event: unknown;
}

FlightExecutionFactDTO and FlightFinishFactDTO extend FactDTO

Validation parameters

const validationPipe = new ValidationPipe({
  whitelist: true,
  forbidNonWhitelisted: true,
});
app.useGlobalPipes(validationPipe);

The error occurs when accessing the 'name' field, when the iteration does not find any matching element. The debugger shows that subType.value is one of the classes that extends FactDTO, and subValue.constructor is FactDTO itself. Of course, no coincidence occurs.

if (this.transformationType === TransformationType.CLASS_TO_PLAIN) {
  subValue[targetType.options.discriminator.property] = targetType.options.discriminator.subTypes.find(
  subType => subType.value === subValue.constructor
  ).name;
}

Expected behavior

The array of incoming objects is validated in accordance with the decorators of each object.

Actual behavior

An error is thrown when trying to match classes, as a result, the 'name' field cannot be read.

@inmativ inmativ added status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature. labels Jul 2, 2021
@smaven
Copy link

smaven commented Aug 23, 2021

@inmativ can you try deleting the dist folder and then start nest again? Re-transpiling the files seems to resolve quite a few issues sometimes.

@inmativ
Copy link
Author

inmativ commented Sep 27, 2021

The error was due to the type "name: string" in the properties of the discriminator.
And these values could not communicate with "eventTypeCode: Enum".
To solve this, us had to use tsIgnore, since you cannot specify "Enum" for the "name" property.

This is what the working code looks like:

@ArrayNotEmpty()
  @ValidateNested()
  @Type(() => NewFactDTO, {
    discriminator: {
      property: 'type',
      subTypes: [
        // @ts-ignore
        { value: NewFlightExecutionFactDTO, name: EventType.FLIGHT_EXECUTION },
        // @ts-ignore
        { value: NewFlightFinishFactDTO, name: EventType.FLIGHT_FINISH },
      ],
    },
    keepDiscriminatorProperty: true,
  })
  facts: (
    | NewFlightExecutionFactDTO
    | NewFlightFinishFactDTO
  )[];

@Ash-Kay
Copy link

Ash-Kay commented Jan 9, 2022

I'm facing same issue, adding // @ts-ignore doesn't help, even tried using strings in name field, still facing the issue, I think it is not related to Enum

Error

TypeError: Cannot read properties of undefined (reading 'name')
at TransformOperationExecutor.transform `(mypath/node_modules/src/TransformOperationExecutor.ts:250:22)

Code:

@ApiExtraModels(BlockDto, IconLinkSectionDto, TextBlockDto)
export class AddNewBlockDto {
    @ApiProperty()
    @IsString()
    blockType: string;

    @ApiProperty({
        type: "object",
        oneOf: [{ $ref: getSchemaPath(IconLinkSectionDto) }, { $ref: getSchemaPath(TextBlockDto) }],
    })
    @IsObject()
    @Type(() => BlockDto, {
        discriminator: {
            property: "blockType",
            subTypes: [
                { value: IconLinkSectionDto, name: "a" },
                { value: TextBlockDto, name: "b" },
            ],
        },
    })
    block: IconLinkSectionDto | TextBlockDto;
}

@kol-93 kol-93 linked a pull request Feb 21, 2022 that will close this issue
6 tasks
@tobinbc
Copy link

tobinbc commented Nov 13, 2023

I'm facing same issue, adding // @ts-ignore doesn't help, even tried using strings in name field, still facing the issue, I think it is not related to Enum

Error

TypeError: Cannot read properties of undefined (reading 'name')
at TransformOperationExecutor.transform `(mypath/node_modules/src/TransformOperationExecutor.ts:250:22)

Code:

@ApiExtraModels(BlockDto, IconLinkSectionDto, TextBlockDto)
export class AddNewBlockDto {
    @ApiProperty()
    @IsString()
    blockType: string;

    @ApiProperty({
        type: "object",
        oneOf: [{ $ref: getSchemaPath(IconLinkSectionDto) }, { $ref: getSchemaPath(TextBlockDto) }],
    })
    @IsObject()
    @Type(() => BlockDto, {
        discriminator: {
            property: "blockType",
            subTypes: [
                { value: IconLinkSectionDto, name: "a" },
                { value: TextBlockDto, name: "b" },
            ],
        },
    })
    block: IconLinkSectionDto | TextBlockDto;
}

For what it's worth, I had the same as you but this was caused by including ApiExtraModels on the field. When removed, the problem goes away.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
status: needs triage Issues which needs to be reproduced to be verified report. type: fix Issues describing a broken feature.
Development

Successfully merging a pull request may close this issue.

4 participants