class-transformer icon indicating copy to clipboard operation
class-transformer copied to clipboard

fix: classToPlain provoke "'constructor' of null" error when used on null class members that defines the discriminator option

Open bpeab opened this issue 3 years ago • 2 comments

Description

Both classToPlain and serialize are provoking the following error TypeError: Cannot read property 'constructor' of null when called on classes that have members with the @Type decorator defining the discriminator option and that's null or undefined once initialized.

Minimal code-snippet showcasing the problem

class Photo {
  @Expose()
  type?: Landscape | Portrait;
  // ...
}

class Landscape extends Photo {
  @Expose()
  type = Landscape;
  // ...
}

class Portrait extends Photo {
  @Expose()
  type = Portrait;
  // ...
}

class Camera {
  @Expose({ name: 'foto' })
  @Type(() => Photo, {
    discriminator: {
      property: 'type',
      subTypes: [
        {
          name: 'Landscape',
          value: Landscape,
        },
        {
          name: 'Portrait',
          value: Portrait,
        },
      ],
    },
  })
  photo?: Landscape | Portrait;
}

const camera = plainToClass(Camera, {});
// or.. new Camera()
console.log(classToPlain(camera));
// or.. console.log(serialize(camera))

Expected behavior

The functions classToPlain and serialize shouldn't treat class members that defines @Type decorator with discriminator option when they are null or undefined.

Actual behavior

The functions classToPlain and serialize fire the following error: TypeError: Cannot read property 'constructor' of null. It's likely that the logic doesn't verify if there's a value before proceeding with the transformation.

The following code snippet (TransformOperationExecutor.js, line 209) should verify if there's value before proceeding (perhaps a simple && subValue added to the condition does the trick).

if (this_1.transformationType === TransformationType.CLASS_TO_PLAIN) {
  subValue[metadata_1.options.discriminator.property] = metadata_1.options.discriminator.subTypes.find(function (subType) { return subType.value === subValue.constructor; }).name;
}

It's likely that is not the only place where it should be fixed.

bpeab avatar Jun 24 '21 21:06 bpeab

I saw that the issue was already solved with #521 but not released. Any ETA on when that could be done ? Thanks

bpeab avatar Jun 24 '21 21:06 bpeab

I have the same problem. Any workaround?

balkarov avatar Jun 17 '22 13:06 balkarov