However, I can't find any Repository.extend method in Repository class and there's nothing about it in the documentation. How to solve this?
typeorm version: "^0.3.0"
I'm using nest js and trying to create a custom repository.
With the current version of TypeORM, it's possible to implement a custom repository in the following way utilizing DataSource.
// user.repository.ts
@Injectable()
export class UsersRepository extends Repository<UsersEntity> {
constructor(private dataSource: DataSource) {
super(UsersEntity, dataSource.createEntityManager());
}
async getById(id: string) {
return this.findOne({ where: { id } });
}
// ...
}
The repository is then injected into the service.
// user.service.ts
export class UserService {
constructor(private readonly userRepository: UserRepository) {}
async getById(id: string): Promise<User> {
return this.userRepository.getById(id);
}
// ...
}
and the module has imports for the feature and the repository as a provider.
// user.module.ts
@Module({
imports: [
TypeOrmModule.forFeature([UserEntity])],
// ...
],
providers: [UserService, UserRepository],
// ...
})
export class UserModule {}
First of all:
npm install @nestjs/typeorm@next
NOTE
In my project @nestjs/typeorm version is 9.0.0-next.2
and typeorm version is 0.3.6
Create a folder named database in the src of your project then create two files in (typeorm-ex.decorator.ts and typeorm-ex.module.ts)
// typeorm-ex.decorator.ts
import { SetMetadata } from "@nestjs/common";
export const TYPEORM_EX_CUSTOM_REPOSITORY = "TYPEORM_EX_CUSTOM_REPOSITORY";
export function CustomRepository(entity: Function): ClassDecorator {
return SetMetadata(TYPEORM_EX_CUSTOM_REPOSITORY, entity);
}
And next file
// typeorm-ex.module.ts
import { DynamicModule, Provider } from "@nestjs/common";
import { getDataSourceToken } from "@nestjs/typeorm";
import { DataSource } from "typeorm";
import { TYPEORM_EX_CUSTOM_REPOSITORY } from "./typeorm-ex.decorator";
export class TypeOrmExModule {
public static forCustomRepository<T extends new (...args: any[]) => any>(repositories: T[]): DynamicModule {
const providers: Provider[] = [];
for (const repository of repositories) {
const entity = Reflect.getMetadata(TYPEORM_EX_CUSTOM_REPOSITORY, repository);
if (!entity) {
continue;
}
providers.push({
inject: [getDataSourceToken()],
provide: repository,
useFactory: (dataSource: DataSource): typeof repository => {
const baseRepository = dataSource.getRepository<any>(entity);
return new repository(baseRepository.target, baseRepository.manager, baseRepository.queryRunner);
},
});
}
return {
exports: providers,
module: TypeOrmExModule,
providers,
};
}
}
Open your AppModule and modify it like the following:
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'mssql',
...
entities: [Photo],
}),
TypeOrmExModule.forCustomRepository([PhotoRepository]),
...
],
controllers: [AppController],
providers: [
AppService
],
})
export class AppModule { }
You can create your customer repository like the following :
@CustomRepository(Photo)
export class PhotoRepository extends Repository<Photo> {
public async getAllPhoto() {
const query = this.createQueryBuilder('photo')
.where('photo.isPublished = :isPublished', { isPublished: true })
const photos = await query.getMany()
return photos
}
}
Everything works perfectly.
Thanks to @anchan828
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With