#Injecting a TypeOrm repository to a dynamic provider

17 messages · Page 1 of 1 (latest)

astral gale
#

I have the following provider defined in my forRootAsync method of my custom module:

{
          provide: RegistrationService,
          useFactory: async (amqpConnection: AmqpConnection, ds: DataSource) => {
            const mappingRepo = ds.getRepository(Mapping)
            const regService = new RegistrationService(mappingRepo, amqpConnection);
            await regService.initializeRoutingKeys();
            console.log(regService.insightsRoutingKeys)
            console.log('Got here')
            return regService;
          },
          inject: [AmqpConnection, DataSource]
        }

This works perfectly, but I was wondering if I can somehow use something like the @simple glenRepository decorator that you can use in a class constructor to inject the mappingRepo directly to the factory method instead of needing to do what I did

lament niche
#

Use getRepositoryToken() to replace @InjectRepository()

astral gale
#

Can you give me an example? Do I need to make another provider for that or just inject a result of this method?

lament niche
#

You can use getRepositoryToken() directly in the inject.

{
          provide: RegistrationService,
          useFactory: async (amqpConnection: AmqpConnection, repo: Repository<Mapping>) => {
            const regService = new RegistrationService(repo, amqpConnection);
            await regService.initializeRoutingKeys();
            console.log(regService.insightsRoutingKeys)
            console.log('Got here')
            return regService;
          },
          inject: [AmqpConnection, getRepositoryToken(Mapping)]
        }
astral gale
#

Ooo nice, and does that mean that I don't need the TypeOrmModule.forFeature in my imports?

lament niche
#

You still need the forFeature. That's what creates the repository token you end up using

astral gale
#

I just tested it and it turns out that for some reason it works even without the import

lament niche
#

That's unexpected. Can you show the module?

astral gale
#
import { AmqpConnection } from '@golevelup/nestjs-rabbitmq';
import { DynamicModule, Module } from '@nestjs/common';
import { getRepositoryToken, TypeOrmModule } from '@nestjs/typeorm';
import { DataSource, Repository } from 'typeorm';
import { Mapping } from '../mapping/mapping.entity';
import { RegistrationController } from './registration.controller';
import { RegistrationService } from './registration.service';

@Module({
  imports: [],
  controllers: [RegistrationController],
  providers: [RegistrationService],
  exports: [RegistrationService],
})
export class RegistrationModule {
  static async forRootAsync(): Promise<DynamicModule> {
    return {
      module: RegistrationModule,
      imports: [],
      controllers: [RegistrationController],
      providers: [
        {
          provide: RegistrationService,
          useFactory: async (amqpConnection: AmqpConnection, mappingRepo: Repository<Mapping>) => {
            const regService = new RegistrationService(mappingRepo, amqpConnection);
            await regService.initializeRoutingKeys();
            return regService;
          },
          inject: [AmqpConnection, getRepositoryToken(Mapping)]
        }
      ],
      exports: [RegistrationService]
    }
  }
}

lament niche
#

And you don't get an error about not being able to find the getRepositoryToken(Mapping) token?

astral gale
#

No, it works fine weirdly enough

lament niche
#

Do you have TypeOrmModule.forFeature([Mapping]) anywhere else, in a global module possibly?

astral gale
#

In another module yes but it's not global

#

That other module is being imported by the same module that imports my RegistrationModule but the other module doesn't export the repo token

#

Ah crap, I get it...
I left the import within the @Module decorator

#

That's why it worked

lament niche
#

That would do it. I just didn't see it in the above file