3
votes

I have these entities in my app.

Category.ts

export class Category {
    @PrimaryGeneratedColumn()
    Id: number

    @Column()
    Name: string

    @OneToMany(type => SubCategory, subcategoy => subcategoy.Category)
    SubCategories: SubCategory[];
}

SubCategory.ts

export class SubCategory {
    @PrimaryGeneratedColumn()
    Id: number

    @Column()
    Name: string

    @ManyToOne(type => Category, category => category.SubCategories)
    @JoinColumn({name: "CategoryId"})
    Category: Category;
}

Now, if I want to add a new sub-category, what should my DTO format be like? I tried the following but the foreign key (CategoryId) was NULL.

SubCategoryDto.ts

export class SubCategoryDto {
    Id: number;
    Name: string;
    CategoryId: number;
}

I understand why the value of CategoryId column was null in database, since CategoryId was tried to be converted to Category, and failed since the two are of a different type. I could do the following but I feel like this just makes the request data bigger (even if it's a bit)

export class SubCategoryDto {
    Id: number;
    Name: string;
    Category: CategoryDto; //has the properties of Id and Name
}

So what should the format of the SubCategoryDto should be? Do I need to transform the DTO to Entity class by fetching the category first from the database and then creating the SubCategory entity? For example:

//request data for new sub-category
{
    Name: "Subcategory 1",
    CategoryId: 1
}

And on the server side

const newSubcategory    = new SubCategory(); //entity class
newSubcategory.Name     = subCategoryDto.Name;
newSubcategory.Category = await this.categoryService.findById(subCategoryDto.CategoryId)
await this.subCategoryService.create(newSubcategory);

However, if I do it this way wouldn't it be an extra database call for? What is the best way of handling this situation? I searched internet all the day and couldn't find something related to this. I guess it is such a simple thing that no one needed to ask, but unfortunately I am not sure how this should be dealt. Any help would be appreciated.

1

1 Answers

1
votes

You need to add CategoryId property in SubCategory entity to allow mapping DTO and entity:

export class SubCategory {
@PrimaryGeneratedColumn()
Id: number

@Column()
Name: string

@Column()
CategoryId: number

@ManyToOne(type => Category, category => category.SubCategories)
@JoinColumn({name: "CategoryId"})
Category: Category;

}

TypeORM automatically generate that column but without the "manual" declaration the field CategoryId of the DTO is tried to be converted in Category entity and failed.