I have a weird behaviour. Nest is complaining about a missing dependency in a service, but only if that service is Injected by multiple other services
cleaning.module.ts
#Module({
imports: [
//Just a few repos
],
providers: [
ServicesService,
...
AreasService,
RoomsService,
...
],
controllers: [
...
],
exports: [
ServicesService,
...
AreasService,
RoomsService,
...
]})
services.module.ts, areas.module.ts and rooms.module.ts are basically the same
#Module({
imports: [CleaningModule],
providers: [],
controllers: [],
exports: []
})
rooms.service.ts
constructor(#InjectRepository(Room) private readonly repo: Repository<Room>, private areasService: AreasService) { }
services.service.ts
constructor(#InjectRepository(Service) private readonly repo: Repository<Service>, ... private roomsService: RoomsService) { }
With this, I get the following error:
ERROR [ExceptionHandler] Nest can't resolve dependencies of the RoomsService (RoomRepository, ?). Please make sure that the argument dependency at index [1] is available in the CleaningModule context.
So, it's missing AreasService somehow. Which is clearly provided by the CleaningModule.
But the weird thing is, if I remove the injection of the RoomsService in the ServicesService constructor, then everything works just fine. And I don't have the slightest idea why this is the case...
Based on the error it seems like you have a circular file import going on from your roo.service.ts to your area.service.ts. This could be several files deep like room.service.ts imports area.service.ts that another that imports another that imports another that finally imports room.service.ts again or it could be the use of barrel files. If this truly is a circular dependency (room uses area which uses room) then you need to use #Inject(forwardRef(() => OtherService)). Otherwise, you need to figure out a way to avoid the circular import
Related
I've followed the instruction from nestjs-redis documentation to register RedisModule but it gives me the following error message. I am new to Nest.js and have no idea how to fix this error.
If you know the better way to use Redis with nestjs, please suggest me.
Nest can't resolve dependencies of the RedisCoreModule
(Symbol(REDIS_MODULE_OPTIONS), ?). Please make sure that the argument
ModuleRef at index [1] is available in the RedisCoreModule context.
Potential solutions:
If ModuleRef is a provider, is it part of the current RedisCoreModule?
If ModuleRef is exported from a separate #Module, is that module imported within RedisCoreModule? #Module({
imports: [ /* the Module containing ModuleRef */ ] })
my app.module
#Module({
imports: [
RedisModule.register({
host: `${host}`,
port: 6379,
}),
],
})
export class AppModule {}
I created service with several repository:
#Injectable()
export class DataService {
constructor(
#InjectRepository(ClassicPrices, 'connect')
private classicPrices: Repository<ClassicPrices>,
#InjectRepository(ModernPrices, 'connect')
private modernPrices: Repository<ModernPrices>,
) {}
public pricesRepository(server): Repository<ModernPrices | ClassicPrices> {
switch (server) {
case 'modern':
return this.modernPrices;
case 'classic':
return this.classicPrices;
}
}
}
Data module settings:
#Module({
imports: [
TypeOrmModule.forFeature([
ClassicPrices,
ModernPrices
], 'connect'),
],
providers: [DataService],
exports: [DataService]
})
export class DataModule {}
When I use it in another modules^ I have error "Nest can't resolve dependencies of the DataService (connect_ClassicPrices). Please make sure that the argument connect_ClassicPrices at index [2] is available in the DataModule context.
Potential solutions:
If connect_ClassicPrices is a provider, is it part of the current DataModule?
If connect_ClassicPrices is exported from a separate #Module, is that module imported within DataModule?
#Module({
imports: [ /* the Module containing connect_ClassicPrices */ ]
})
How to export repository ?
If you want to use a repository from DataModule in other modules you need to add TypeOrmModule to the exports array in DataModule:
exports: [DataService, TypeOrmModule]
Then, any module that imports DataModule can use the repositories registered with TypeOrmModule.forFeature. Generally it's a better practice to export just the services and keep the repositories scoped to their module because that makes your app more modular.
I am building a nestjs app where I want to create a rabbitmq
#Module({
imports: [
ClientsModule.register([
{
name: 'rabbitmq',
transport: Transport.RMQ,
options: {
urls: [
'amqp://guest:guest#rabbitmq',
],
queue: 'my_queue',
},
},
]),
],
controllers: [],
providers: [RabbitMQService],
exports: [RabbitMQService],
})
And service:
#Injectable()
export class RabbitMQService {
constructor(
#Inject('rabbitmq') private client: ClientProxy
) {}
}
The error I am getting is: Nest can't resolve dependencies of the RabbitMQService (?). Please make sure that the argument rabbitmq at index [0] is available in the RabbitMQService context.
As much I am aware, this should work, but nope. Could anyone help?
From the error, it looks like somewhere in your application you have RabbitMQService in an imports array where #Module() classes are supposed to go. Make sure that you keep providers and other #Injectables() to the providers array and keep #Module() and other DynamicModules to the imports array. Common error docs
I get this error
Nest can't resolve dependencies of the WorkspaceController (?). Please make sure that the argument API_SERVICE at index [0] is available in the WorkspaceModule context.
I have this code
app.module.ts
#Module({
imports: [
ClientsModule.register([
{
name: 'API_SERVICE',
transport: Transport.REDIS,
options: {
url: 'redis://localhost:6379'
}
}
]),
WorkspaceModule
],
controllers: [AppController],
providers: [AppService]
})
workspace.module.ts
#Module({
imports: [],
controllers: [WorkspaceController]
})
export class WorkspaceModule {}
workspace.controller.ts
#Controller()
export class WorkspaceController{
constructor(#Inject('API_SERVICE') private client: ClientProxy) {}
#Get("default-languages")
getDefaultLanguages():Observable<string[]> {
return this.client.send<any>({cmd:'getDefaultLanguages'},{});
}
}
You register the ClientsModule inside of AppModule which means that controlelrs and providers in AppModule's scope (i.e. in its own providers and controllers arrays) have access to that provider (#Inject('API_SERVICE')), but once you leave to another module's scope (like WorkspaceModule), that provider is no longer available. If you need that microservice client in several different modules, I'd suggest making a wrapper module for it, that imports and exports the ClientsModule, otherwise, you just need to move the ClientsMOdule.register from AppModule to WorkspaceModule
Example Wrapper
#Module({
imports: [ClientsModule.register(clientsModuleOptions)],
exports: [ClientsModule],
})
export class WrapperClientsModule {}
It's called module re-exporting
The official doc is not clear about how modules in nestjs work and I'm having a problem with a circular dependency. It seems like my module structure is messed up I would like to understand what is wrong with it. The error I'm getting reads:
Nest cannot create the module instance. Often, this is because of a
circular dependency between modules. Use forwardRef() to avoid it.
(Read more: https://docs.nestjs.com/fundamentals/circular-dependency)
Scope [AppModule -> UsersModule -> CategoriesModule]
Here are the import parts of all the modules mentioned in the error message.
AppModule:
UsersModule,
SmsRegistrationModule,
AuthModule,
SubscriptionModule,
EmailModule,
EntriesModule,
CategoriesModule,
AwsModule,
SharedModule
UsersModule:
CategoriesModule
CategoriesModule:
AwsModule,
SharedModule,
The error raised when I added SharedModule to the CategoriesModule module. Seems like I'm missing something on how these modules communicate and thus can't resolve this error.
Your help would be much apprecicted.
EDIT:
SharedModule:
#Module({
providers: [
CacheService,
CodeGenService,
IsUniqueEmail,
BasicFileService,
],
imports: [
CacheModule.registerAsync({
imports: [ConfigModule],
useClass: CacheConfigService,
}),
UsersModule,
AwsModule,
],
exports: [
CacheService,
CodeGenService,
IsUniqueEmail,
BasicFileService,
],
})
export class SharedModule {}
Your SharedModule imports UserModule, so the import chain (or at least the one I'm going to follow here) is AppModule -> UsersModule -> CategoriesModule -> SharedModule -> UsersModule -> CategoriesMOdule -> SharedModule -> .... To get around this, either the SharedModule should not import the UsersModule, or you should forward reference the CategoriesModule from the UserModule, the UserModule from the SharedModule and the SharedModule from the CategoriesModule. This is my first time seeing a circular dependency a few modules deep, so I can't give the exact syntax of how to work with the forwardRef method.