How to do custom repository using TypeORM (MongoDB) in NestJS?

Issue

I have a question. With @EntityRepository decorator being marked as deprecated in typeorm@^0.3.6, what is now the recommended or TypeScript-friendly way to create a custom repository for an entity in NestJS? A custom repository before would look like this:

// users.repository.ts
import { EntityRepository, Repository } from 'typeorm';
import { User } from './user.entity';

@EntityRepository(User)
export class UsersRepository extends Repository<User> {
  async createUser(firstName: string, lastName: string): Promise<User> {
    const user = this.create({
      firstName,
      lastName,
    });

    await this.save(user);

    return user;
  }
}

And since NestJS is by default configured with TypeScript support, I will be able to call usersRepository.createUser() without an issue in a service like this:

// users.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersRepository } from './users.repository';

@Injectable()
export class UsersService {
  constructor(
    @InjectRepository(UsersRepository)
    private readonly usersRepository: UsersRepository,
  ) {}

  async createUser(firstName: string, lastName: string): Promise<User> {
    return this.usersRepository.createUser(firstName, lastName);
  }
}

This is how the modules would import the custom repository:

// users.module.ts
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersRepository } from './users.repository';
import { UsersService } from './users.service';

@Module({
  imports: [TypeOrmModule.forFeature([UsersRepository])],
  controllers: [UsersController],
  providers: [UsersService],
  exports: [UsersService],
})
export class UsersModule {}

Also the reason why I mentioned MongoDB here is because I tried using typeorm@0.2 where @EntityRepository is still supported but I receive an error when I tried to import it in the module stating Repository not found or something. Do note, if I chose postgresql as my database in TypeORM with the same changes above, I don’t have this issue. Hence I went to check the latest only to find out it is already deprecated, I also didn’t find any example in NestJS documentation.

Solution

The way you can create a custom repository for mongo in TypeORM it with the following way:

users.repository.ts

Here instead of using @EntityRepository you will use the @Injectable decorator, and for inject, the schema will use MongoRepository

// users.repository.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { MongoRepository } from 'typeorm';
import { User } from './user.entity';
@Injectable()
export class UsersRepository {
  constructor(
    @InjectRepository(User)
    private readonly usersRepository: MongoRepository<User>,
  ) {}

  async createUser(firstName: string, lastName: string): Promise<User> {
    const user = new User({
      firstName,
      lastName,
    });

    await this.usersRepository.save(user);

    return user;
  }
}

users.service.ts

import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { User } from './user.entity';
import { UsersRepository } from './users.repository';

@Injectable()
export class UsersService {
  constructor(private readonly usersRepository: UsersRepository) {}

  async createUser(firstName: string, lastName: string): Promise<User> {
    return this.usersRepository.createUser(firstName, lastName);
  }
}

users.module.ts

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { UsersController } from './users.controller';
import { UsersRepository } from './users.repository';
import { UsersService } from './users.service';
import { User } from './user.entity';
import { UsersRepository } from './database/repository/UsersRepository';
@Module({
  imports: [TypeOrmModule.forFeature([User])],
  controllers: [UsersController],
  providers: [UsersRepository, UsersService],
  exports: [UsersService],
})
export class UsersModule {}

Answered By – Martinez

Answer Checked By – Dawn Plyler (AngularFixing Volunteer)

Leave a Reply

Your email address will not be published.