How to convert plain to instance of a junction entity (many-to-many)

26 Views Asked by At

I have an Item, Photo, and ItemPhoto entities with a many-to-many relationship. I'm using TypeORM and class-transformer to convert plain objects to entities. These are the classes:

    @Entity()
    export class Item extends BaseModel {
        /*
          ...more fields
        */
        @ValidateNested({each: true})
        @Type(() => ItemPhoto)
        @OneToMany(() => ItemPhoto, itemPhoto => itemPhoto.item , {nullable: true})
        photos: ItemPhoto[]
    }

    @Entity()
    export class Photo extends BaseModel {
        @IsUrl()
        @IsNotEmpty()
        @Column({nullable: false})
        url: string
    }

    @Entity()
    export class ItemPhoto extends BaseModel {
        @IsDefined()
        @Type(() => Item)
        @ManyToOne(() => Item, (item) => item.photos, {nullable: false})
        item: Item

        @IsDefined()
        @Type(() => Photo)
        @ManyToOne(() => Photo, {nullable: false})
        photo: Photo
    }

and I have a DTO entity for HTTP requests to create an Item:

    export class ItemDto {
        /*
          ...more fields
        */
        @ArrayNotEmpty()
        @IsUrl({}, {each: true})
        photos: string[]

        toItemEntity() {
            const {photos, ...rest} = this
            return plainToInstance(Item, {
                ...rest,
                photos: plainToInstance(ItemPhoto, photos.map((photoUrl) => ({
                    photo: plainToInstance(Photo, { url: photoUrl }),
                    item: // <-- this is where I strugle to understand
                }))),
            })
        }
    }

my questions is, how do I create the ItemPhoto if it needs to get item as one of its properties? Is this code which seems a bit ugly and creates a loop a dicent approach?

    toItemEntity() {
        const {photos, ...rest} = this
        const itemEntity = plainToInstance(Item, {
            ...rest,
            photos: plainToInstance(ItemPhoto, photos.map((photoUrl) => ({
                photo: plainToInstance(Photo, { url: photoUrl }),
            }))),
        })
        itemEntity.photos = itemEntity.photos.map(itemPhoto => plainToInstance(ItemPhoto, {
            item: itemEntity,
            photo: itemPhoto.photo
        }))
        return itemEntity
    }

0

There are 0 best solutions below