Closed andreasvh-conceto closed 4 months ago
Hi @andreasvh-conceto, Thank you for the detailed issue and sorry for a late reply.
The error you got is a typescript error and nothing to do with this library.
The error clearly states that 'Types of property 'photos' are incompatible.' You used the Partial<AlbumDto>
, but AlbumDto contains 'photos: PhotoDto[]', which is not Partial, so when you instantiate with an object containing photos
, it will require you to be compatible with 'PhotoDto'. (so Partial
But this is not the way you would want to use class-transformer
. Here is a snippet for your scenario which will work:
class AlbumDto {
id: number;
name: string;
@Type(() => PhotoDto)
photos: PhotoDto[];
@Expose()
get title(): string {
return "My super album";
}
}
class PhotoDto {
@Expose()
filename: string;
@Expose()
get author(): string {
return "John";
}
}
describe("transmission detail response dto serialization test", () => {
it("learning test nested objects", () => {
const albumPartial = {
id: 1,
name: "My Album",
photos: [{ filename: "photo1.jpg" }, { filename: "photo2.jpg" }],
};
const album = plainToInstance(AlbumDto, albumPartial);
expect(album.id).toEqual(1);
expect(album.name).toEqual('My Album');
expect(album.photos[0].filename).toEqual('photo1.jpg');
expect(album.photos[1].filename).toEqual('photo2.jpg');
expect(instanceToPlain(album)).toEqual({
id: 1,
name: 'My Album',
photos: [
{ filename: 'photo1.jpg', author: 'John' },
{ filename: 'photo2.jpg', author: 'John' }
],
title: 'My super album'
});
});
});
Thank you for the detailed explanation. This helps! Best regards :)
Hi @diffy0712
one question came into my mind, while playing around with your answer. When i choose to @Expose({name: "myPropertyName"})
the plainToInstance
method returns undefined for the annotated property. Currently i handle that using the ignoreDecorators: true
option like this:
const album = plainToInstance(AlbumDto, albumPartial, {
ignoreDecorators: true, // this prevents that the property will be undefined, since it is keeping the property name from the created instance
});
Is this the right approach to go for?
Thanks a lot and best regards
Hello @andreasvh-conceto,
if you provide @Expose({name: "myPropertyName"})
decorator to the name
property, when calling plainToInstane
, it will expect your plain to have a property called 'myPropertyName' instead of the real property name
, which I assume you did not provide in your plain object, so it was set to undefined.
I would not suggest to use ignoreDecorators
for this, as it is the same as not using the decorator in your situation.
So updating my previous example:
// if you add
@Expose({name: "myPropertyName"})
name: string;
// then you plain would needs to change to
const albumPartial = {
id: 1,
myPropertyName: "My Album",
photos: [{ filename: "photo1.jpg" }, { filename: "photo2.jpg" }],
};
NOTE: if you override the name in expose, then you will get that name in your instanceToPlain
result as well. If you need to override name only on one way please use the options toPlainOnly
or toClassOnly
. @Expose({name: "myPropertyName", toClassOnly: true})
Please read the documentation a bit more in detail, because everything I have wrote here is already in the documentations!
Hope this helps.
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.
Hello,
i was trying to serialize a Dto in a jest test, which contains a nested array of another dto.
The problem: I receive the following error:
const album = new AlbumDto(albumPartial);
The error:Here iam a little bit confused, why this error is happening for the nested dto? - it is also instantiated via a partial! If i remove the
getAuthor
method from thePhotoDto
everything is fine. So on the first level there are no issues adding methods. But i would also not expect any issues in the nested levels, because it is just a partial i need to pass to the constructor right? So propertyname
would be enough in thealbumPartial.photos
objects.How to solve the issue in the best way? I know that i can also instantiate
new PhotoDto
in the album like this:But this looks ugly and enforces me to do this for every nested object in my
albumPartial
. Not to imagine having nested in nested Objects.Any solutions or ideas?
Thanks and best regards