Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

NestJS & TypeORM: DTO format in post request

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.

like image 541
reika Avatar asked Oct 18 '25 18:10

reika


1 Answers

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.

like image 61
Giuseppe Pace Avatar answered Oct 20 '25 08:10

Giuseppe Pace