typestack / class-transformer

Decorator-based transformation, serialization, and deserialization between objects and classes.
MIT License
6.74k stars 493 forks source link

question: how can I expose my custom getter? #1060

Closed simplenotezy closed 1 month ago

simplenotezy commented 2 years ago

I've tried to define a custom getter like this:

import { Expose } from 'class-transformer';

export class MyDTOResponse {
  @Expose()
  id: string;

  @Expose()
  name: string;

  @Expose()
  get thisIsATest(): string {
    return 'yolo';
  }
}

This is how I transform it:

plainToClass(MyDTOResponse, MyRawDataObject, {
  excludeExtraneousValues: true,
});

As described in the documentation here: https://github.com/typestack/class-transformer#exposing-getters-and-method-return-values

However, the response is only:

{
  "id": "f8c213c7-5853-4d01-b424-cb0349a6c580",
  "name": "Clean the kitchen!"
}

I am not sure what I am doing wrong exactly, but I am missing the "thisIsATest" property.

DmytroMysak commented 2 years ago

Also having the same issue. As workaround moved getter to Transform like:

export class MyDTOResponse {
  @Expose()
  id: string;

  @Expose()
  name: string;

  @Expose()
  @Transform(() => 'yolo')
  thisIsATest: string;
}
groch2 commented 2 years ago

It is not an issue with class-transformer. Getter inside javascript class are not exposed at serialization. You must customize the serialization process by creating a custom toJSON method inside your class.

q815101630 commented 2 years ago

Also having the same issue. As workaround moved getter to Transform like:

export class MyDTOResponse {
  @Expose()
  id: string;

  @Expose()
  name: string;

  @Expose()
  @Transform(() => 'yolo')
  thisIsATest: string;
}

Thanks, I met the same problem. Here's my workaround for exposing a new field based on existing field:

@Expose()
@Transform(({ obj }) => `${obj.id}+${obj.name}`)
idName: string;

where obj refers to the source object. https://github.com/typestack/class-transformer#advanced-usage

edkhrian commented 2 years ago

@simplenotezy I guess it's late, but anyway. Main purpose of plainToClass (plainToInstance) is to bind your plain object fields to class properties, so It doesn't really need to call your class getters. To make your getters called you need to transfer instance of your class back to plain object like so:

classToPlain(plainToClass(MyDTOResponse, MyRawDataObject));
t-ega commented 1 month ago

This is absolutely right. Solved the issue. Thanks @edkhrian!

diffy0712 commented 1 month ago

Closing as answered! Thank you @edkhrian for your answer.

github-actions[bot] commented 5 hours ago

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.