how to use multiple entities single resource nestjs

Multiple Entities in Single Resource (NestJS)

Maybe it happened to you that you want to use several entities in one resource. Here we mean by resource what you create by the nest g resource command, which creates this new resource’s controller, service, and module.

Imagine that we are developing a drug information system as the backend and our API, and each drug in this system has characteristics. For example, basic drug information, drug interactions, side effects, etc.

Naturally, separating this information from each other will help our database to be clean, and it is a very bad approach to try to gather all this information in one entity (as such, in a single database table).

But the point is that we don’t want to create a new resource for each of these entities, such as basic drug information, drug interactions, or side effects, which has a controller, service, module, etc.
Instead, we can create a resource and add any entity we need in its entities folder.

1. Install Nest-CLI & Generate Resource

If you haven’t installed Nest CLI yet, install this package to work with Nest commands in the command line.

npm i -g @nestjs/cli

We will start this process by typing this command in the terminal, inside the project folder.

nest g resource

Next, it asks us for the name of the resource we want to create, and its type (rest, microservice, etc.), then it’ll generate the resource including controller, service, module, and test files. In this section, we enter the name of our resource (drugs, for example).

2. Creating Our Entities

We create our first entity file, named:

import { Column, Entity, OneToMany, PrimaryGeneratedColumn } from 'typeorm';
import { AdverseEffects } from './adverse-effects.entity';

@Entity()
export class BasicInformation {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  Name: string;

  @Column()
  Strength: string;

  @Column({ nullable: true })
  Description: string;

  @Column()
  Molecule: string;

  @OneToMany(() => AdverseEffects)
  AdverseEffects: AdverseEffects[];
}

Then, as the second entity, we can create:

import { Column, Entity, ManyToOne, JoinColumn, PrimaryGeneratedColumn } from 'typeorm';
import { BasicInformation } from './basic-information.entity';

@Entity()
export class AdverseEffects {
  @PrimaryGeneratedColumn()
  id: number;

  @Column()
  Type: string;

  @Column()
  Time: string;

  @Column({ nullable: true })
  Description: string;

  @ManyToOne(() => BasicInformation)
  @JoinColumn()
  BasicInformation: BasicInformation;
}

3. Adding Entities in the Module

Now that we have these two entities, in order to use them, we must bring them into the drug module so that our resource recognizes these two entities.

Otherwise, we will encounter the following error:

UnhandledPromiseRejectionWarning: 
Error: Entity metadata for entity*** was not found. Check if you specified a correct entity object and if it's connected in the connection options.

So, the fix for this error is simply to inject our entities in our module like this:

import { Module } from '@nestjs/common';
import { DrugsService } from './drugs.service';
import { DrugsController } from './drugs.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { BasicInformation } from './entities/basic-information.entity';
import { AdverseEffects } from './entities/adverse-effects.entity';

@Module({
  imports: [
    TypeOrmModule.forFeature([
      BasicInformation,
      AdverseEffects,
    ]),
  ],
  controllers: [DrugsController],
  providers: [
    DrugsService,    
  ],
})
export class DrugsModule {}

4. Using Entities with Repository in Service

Now, to use the entities we can simply inject their repository into the drugs service:

@Injectable()
export class DrugsService {
  constructor(
    @InjectRepository(BasicInformation)
    private basicInformationRepository: Repository<BasicInformation>,
    @InjectRepository(AdverseEffects)
    private adverseEffectsRepository: Repository<AdverseEffects>,
    ...) {}
  async findDrug(id: number) {
...

In this way, we can use both entities inside a single resource. easy, right?!

Note: It is not needed to inject the entities that we have injected in a module (for example, the drugs module) into the app module. Instead, we import the module itself (for example, the drugs module) into the app module.