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 {}