Reputation: 737
I have an issue with NestJS and it appears to be for just 1 module and all the others work fine. I have the following modules.
The error is:
[ExceptionHandler] Nest can't resolve dependencies of the ApplicationService (ApplicationModel, AwsService, UserService, ?, JobService). Please make sure that the argument at index [3] is available in the ApplicationModule context.
The AgencyService
is [3]
. If I remove the AgencyModule
from the ApplicationModule
NestJS successfully compiles and I can make API calls.
AgencyModule,
ApplicationModule,
AuthModule,
JobModule,
UserModule,
All these modules are required by other modules for their service providers so rather than import them between each other using forwardRef()
I just made them Global()
- May not be best practice but hey ho (it works).
My AppModule
file.
@Module({
imports: [
MongooseModule.forRootAsync({
useFactory: (configService: ConfigService) => ({
uri: configService.get('MONGO_DB_URL'),
useNewUrlParser: true,
}),
imports: [ConfigModule],
inject: [ConfigService],
}),
ConfigModule,
AgencyModule,
ApplicationModule,
AuthModule,
DevModule,
JobModule,
UserModule,
VideoModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Each module folder has the following structure.
agency/
- dto/
- agency.controller.ts
- agency.interface.ts
- agency.schema.ts
- agency.service.ts
- agency.module.ts
My AgencyModule
file.
@Global()
@Module({
imports: [
SharedModule,
MongooseModule.forFeature([{ name: 'Agency', schema: AgencySchema }]),
],
controllers: [
AgencyController,
],
providers: [
AgencyService,
AwsService,
],
exports: [
AgencyService,
],
})
export class AgencyModule implements NestModule {
public configure(consumer: MiddlewareConsumer) {
consumer
.apply()
.forRoutes(
{ path: 'agency', method: RequestMethod.GET },
);
}
}
My AgencyService
file.
@Injectable()
export class AgencyService {
constructor(
@InjectModel('Agency') private readonly agencyModel: Model<Agency>,
private readonly awsService: AwsService,
private readonly applicationService: ApplicationService,
) {
//
}
// More stuff here but not worth adding to the snippet.
}
My ApplicationModule
file.
@Global()
@Module({
imports: [
SharedModule,
MongooseModule.forFeature([{ name: 'Application', schema: ApplicationSchema }]),
],
controllers: [
ApplicationController,
],
providers: [
ApplicationService,
AwsService,
],
exports: [
ApplicationService,
],
})
export class ApplicationModule implements NestModule {
public configure(consumer: MiddlewareConsumer) {
consumer
.apply()
.forRoutes(
{ path: 'application', method: RequestMethod.GET },
);
}
}
My ApplicationService
file.
@Injectable()
export class ApplicationService {
constructor(
@InjectModel('Application') private readonly applicationModel: Model<Application>,
private readonly awsService: AwsService,
private readonly userService: UserService,
private readonly agencyService: AgencyService,
private readonly jobService: JobService,
) {
//
}
// More stuff here but not worth adding to the snippet.
}
The AwsService
is a shared service without a module.
Upvotes: 2
Views: 2060
Reputation: 60347
Using @Global()
does not automatically resolve circular dependencies, you still have to use @Inject(forwardRef(() => MyService))
on both sides, see the docs.
As you noted yourself, circular dependencies (forwardRef
) and global modules (@Global
) are bad style and should be avoided. Rather make your dependencies explicit. If you encounter a circular dependency extract the commonly used parts in a shared service/module that is imported by both sides, see this thread.
Upvotes: 2