Home > Software design >  Nest TypeScript error: Nest can't resolve dependencies of the ChildService
Nest TypeScript error: Nest can't resolve dependencies of the ChildService

Time:02-05

I have a class structure something like this:

I have a ChildModule inside the libs/childmodule/src/child.module.ts. I have a taconfig.json which this is mapped to @app.

Then I have a parentModule where I am trying to import the ChildModule. Codewise:

ChildModule:


import { Module } from '@nestjs/common';
import { ChildService } from './child.service';
import { LoggerModule } from '@app/logger';
import { CommonModule } from '@app/common';
import { SecretsModule } from '@app/secrets';

@Module({
  providers: [ChildService],
  exports: [ChildService],
  imports: [
    LoggerModule,
    CommonModule,
    SecretsModule,
  ],
})
export class ChildModule {}

My ParentModule is as follows:

import { ChildModule } from '@app/child';

@Module({
  imports: [SomeModule, LoggerModule, ChildModule],
  controllers: [ParentController],
  providers: [ParentService],
  exports: [ParentService],
})
export class ParentModule {}

I even did not used this ChildSevice yet through DI.

The error I am getting:

Error: Nest can't resolve dependencies of the ChildService (LoggerService, CommonService, ?). Please make sure that the argument SecretsService at index [2] is available in the ChildModule context.

Potential solutions:
- If SecretsService is a provider, is it part of the current ChildModule?
- If SecretsService is exported from a separate @Module, is that module imported within ChildModule?
  @Module({
    imports: [ /* the Module containing SecretsService */ ]
  })

The best I know if I can import a module (ChildModule in my case) into parent, then all of ChildModule dependencies will be resolved. I mean I need not to manually keep on mention in my parent module's providers all the dependencies of ChildModule.

Not able to get any clue what is missing here.

For further clarity, adding here the SecretsModule:

SecretsModule

import { Global, Module } from '@nestjs/common';
import { ConfigModule, ConfigService } from '@nestjs/config';
import { SecretsService } from './secrets.service';
import { Module1Module, Module1Service } from '@app/module1';

@Global()
@Module({})
export class SecretsModule {
  static forRoot(some_key) {
    return {
      module: SecretsModule,
      imports: [Module1Module, ConfigModule],
      providers: [
        {
          provide: SecretsService,
          useFactory: async (
            configService: ConfigService,
            service1: Module1Service,
          ) => {
            const secretsService = new SecretsService(
              configService,
              service1,
              some_key,
            );
            await secretsService.init();
            return secretsService;
          },
          inject: [ConfigService, Module1Service],
        },
      ],
      exports: [SecretsService],
    };
  }
}

CodePudding user response:

The third parameter in the ChildService constructor is SecretsService. The SecretsService probably is in SecretsModule. So to have the SecretsService in the ChildModule context, you need to put the service as an exporter in SecretsModule, then you can use this service in every module that you would want by importing the related module.

So the changes would be:

//secrets.module.ts
@Module({
  imports: [...],
  controllers: [...],
  providers: [...],
  exports: [SecretsService],
})
export class SecretsModule {}

Do the same thing if you have any other case like this.


Updated:

Since SecretsModule is a dynamic module, you need to call forRoot in each module you would want to import SecretModule, otherwise, Nest couldn't import it.

//child.module.ts
@Module({
  providers: [ChildService],
  exports: [ChildService],
  imports: [
    LoggerModule,
    CommonModule,
    SecretsModule.forRoot(/*since forRoot take parameter `some_key`, you need to pass it here*/),
  ],
})
export class ChildModule {}

  • Related