From 6193ea28df6fc9310ab917f018230e3b7e5aacde Mon Sep 17 00:00:00 2001 From: Manuel Nascimento <57446204+Manuel-Antunes@users.noreply.github.com> Date: Wed, 1 Mar 2023 05:02:13 -0300 Subject: [PATCH] feat: implement auto EagerLoads in library (#506) --- README.md | 40 +++++++++++++++++++++++++++++++++++++ src/__tests__/cat.entity.ts | 4 +++- src/paginate.spec.ts | 20 +++++++++++++++++++ src/paginate.ts | 8 ++++++++ 4 files changed, 71 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 348e0a2..d3f9be7 100644 --- a/README.md +++ b/README.md @@ -261,6 +261,46 @@ const paginateConfig: PaginateConfig { } ``` +## Eager loading + +Eager loading should work with typeorm's eager property out the box. Like so + +```typescript +import { Entity, OneToMany } from 'typeorm'; + +@Entity() +export class CatEntity { + @PrimaryGeneratedColumn() + id: number + + @Column('text') + name: string + + @Column('text') + color: string + + @Column('int') + age: number + + @OneToMany(() => CatToyEntity, (catToy) => catToy.cat, { + eager: true, + }) + toys: CatToyEntity[] +} + +// service +class CatService { + constructor(private readonly catsRepository: Repository) {} + + public findAll(query: PaginateQuery): Promise> { + return paginate(query, this.catsRepository, { + sortableColumns: ['id', 'name', 'color', 'age'], + loadEagerRelations: true // set this property as true to enable the eager loading + }) + } +} +``` + ## Usage with Query Builder You can paginate custom queries by passing on the query builder: diff --git a/src/__tests__/cat.entity.ts b/src/__tests__/cat.entity.ts index 6ba7373..4b60bfd 100644 --- a/src/__tests__/cat.entity.ts +++ b/src/__tests__/cat.entity.ts @@ -32,7 +32,9 @@ export class CatEntity { @Column(() => SizeEmbed) size: SizeEmbed - @OneToMany(() => CatToyEntity, (catToy) => catToy.cat) + @OneToMany(() => CatToyEntity, (catToy) => catToy.cat, { + eager: true, + }) toys: CatToyEntity[] @OneToOne(() => CatHomeEntity, (catHome) => catHome.cat, { nullable: true }) diff --git a/src/paginate.spec.ts b/src/paginate.spec.ts index 644d2a2..c5c7a38 100644 --- a/src/paginate.spec.ts +++ b/src/paginate.spec.ts @@ -1981,4 +1981,24 @@ describe('paginate', () => { expect(result.data.length).toBe(4) }) + + it('should return eager relations when set the property `loadEagerRelations` as true', async () => { + const config: PaginateConfig = { + sortableColumns: ['id'], + defaultSortBy: [['id', 'ASC']], + loadEagerRelations: true, + searchableColumns: ['name'], + } + + const query: PaginateQuery = { + path: '', + search: 'Garfield', + } + + const result = await paginate(query, catRepo, config) + + expect(result.data[0].toys).toBeDefined() + + expect(result.data[0].toys).toHaveLength(1) + }) }) diff --git a/src/paginate.ts b/src/paginate.ts index 2dd022e..52efb1b 100644 --- a/src/paginate.ts +++ b/src/paginate.ts @@ -5,6 +5,7 @@ import { FindOptionsWhere, FindOptionsRelations, ObjectLiteral, + FindOptionsUtils, } from 'typeorm' import { PaginateQuery } from './decorator' import { ServiceUnavailableException, Logger } from '@nestjs/common' @@ -62,6 +63,7 @@ export interface PaginateConfig { filterableColumns?: { [key in Column]?: (FilterOperator | FilterSuffix)[] } + loadEagerRelations?: boolean withDeleted?: boolean relativePath?: boolean origin?: string @@ -146,6 +148,12 @@ export async function paginate( const queryBuilder = repo instanceof Repository ? repo.createQueryBuilder('__root') : repo + if (repo instanceof Repository && !config.relations && config.loadEagerRelations === true) { + if (!config.relations) { + FindOptionsUtils.joinEagerRelations(queryBuilder, queryBuilder.alias, repo.metadata) + } + } + if (isPaginated) { // Switch from take and skip to limit and offset // due to this problem https://github.com/typeorm/typeorm/issues/5670