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
});