Home > Software engineering >  serialize nested objects using class-transformer : Nest js
serialize nested objects using class-transformer : Nest js

Time:07-03

I am trying to serialize nested objects using a class transformer. I have two dtos like below. When I am trying to serialize using plainToClass the nested object gets removed from the output. only getting the parent object's data.

User dto:

export class UserDto extends AbstractDto {
    @Expose()
    email: string;

    @Expose()
    first_name: string;

    @Expose()
    last_name: string;

    @Expose()
    profile: ProfileDto

}

Profile dto:

export class ProfileDto extends AbstractDto {
    @Expose()
    date_of_birth: string;

    @Expose()
    address: string;

    @Expose()
    pincode: string;
}

Serializer:

const serialized = plainToClass(UserDto, user, {
    excludeExtraneousValues: true,
});

Expected Output:

{
    email:'[email protected]',
    first_name: 'test',
    last_name: 'test',
    profile: {
        date_of_birth: '',
        address: '',
        pincode: ''
    }
}

CodePudding user response:

This question is not related to NestJS, but purely to class-transformer. NestJS might happen to use the class-validator & class-transformer packages as part of its pipes feature, but in the context of this question NestJS doesn't even need to be considered.

Let's assume you have two classes, Cat and Owner. An owner can have a cat.

class Cat {
  @Expose()
  name: string;

  @Expose()
  age: number;

  favoriteFood: string;

  constructor(name: string, age: number, favoriteFood: string) {
    this.name = name;
    this.age = age;
    this.favoriteFood = favoriteFood;
  }
}

class Owner {
  @Expose()
  name: string;

  @Expose()
  cat: Cat;

  constructor(name: string, cat: Cat) {
    this.name = name;
    this.cat = cat;
  }
}

Let's instantiate an instance of each.

const cat = new Cat('Misty', 6, 'Dry cat food');
const owner = new Owner('Christophe', cat);

If you want to convert the owner instance back into a plain JavaScript object then use the instanceToPlain() function with the excludeAll strategy from class-transformer. The classToPlain() function is deprecated.

const serialized = instanceToPlain(owner, { strategy: 'excludeAll' });

That will only serialize the properties you decorated with the @Expose() decorator:

{ name: 'Christophe', cat: { name: 'Misty', age: 6 } }

The plainToClass() you used in your example is meant to convert a plain JavaScript back into an instance of the Owner class, or for "deserializing" rather.

For more information consult the class-transformer documentation.

https://github.com/typestack/class-transformer

CodePudding user response:

I have found the answer here Link. If I add enableImplicitConversion: true along with the @Type decorator then it is working as expected.

export class UserDto extends AbstractDto {
    @Expose()
    email: string;

    @Expose()
    first_name: string;

    @Expose()
    last_name: string;

    @Expose()
    @Type(() => ProfileDto)
    profile: ProfileDto

}

Serializer:

const serialized = plainToClass(UserDto, user, {
    excludeExtraneousValues: true,
    enableImplicitConversion: true
    
});
  • Related