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
Related
I'm trying to setup a graphql nestjs clean architecture, I have my resolver call the service, service calls repository and repository calls orm methods. Am I missing a step?
But I get this error:
[Nest] 59764 - 03/10/2022, 16:36:13 ERROR [ExceptionHandler] Nest can't resolve dependencies of the AthleteRepository (?). Please make sure that the argument AthleteEntityRepository at index [0] is available in the GraphQLModule context.
Potential solutions:
- If AthleteEntityRepository is a provider, is it part of the current GraphQLModule?
- If AthleteEntityRepository is exported from a separate #Module, is that module imported within GraphQLModule?
#Module({
imports: [ /* the Module containing AthleteEntityRepository */ ]
})
Error: Nest can't resolve dependencies of the AthleteRepository (?). Please make sure that the argument AthleteEntityRepository at index [0] is available in the GraphQLModule context.
This is my module:
#Module({
imports: [
InfraestructureModule,
NestGraphqlModule.forRoot<MercuriusDriverConfig>({
driver: MercuriusDriver,
graphiql: true,
autoSchemaFile: join(
process.cwd(),
'src/infraestructure/graphql/schema.gql',
),
sortSchema: true,
}),
],
controllers: [AuthResolver, UserResolver],
providers: [
FirebaseService,
AthleteEntity,
AthleteRepository,
AthleteService,
],
})
export class GraphQLModule {}
Adding repository by comment request, it's mostly just wrappers around the typerom Repository.
import { Controller } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
import { AthleteEntity } from '../entity/athlete.entity';
#Controller('')
export class AthleteRepository {
constructor(
#InjectRepository(AthleteEntity)
private athleteRepository: Repository<AthleteEntity>,
) {}
async getAthleteByUserId(id: string): Promise<AthleteEntity> {
return this.athleteRepository.findOne({ where: { id } });
}
async getAthletes(): Promise<AthleteEntity[]> {
return this.athleteRepository.find();
}
}
As you use #InjectRepository(AtheleteEntity) you need to have TypeOrmModule.forFeature([AtheleteEntity]) used in the imports of the GraphQlModule.
Side note: Is that supposed to be #Controller() or #Injectable()? It doesn't look like a standard HTTP or RPC controller to me
change AthleteRepository to an #Injectable instead of #Controller.
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
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 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
So I followed the guide on how to create a configuration for my Nest app
https://docs.nestjs.com/techniques/configuration
and due to the fact I have many configuration parts I wanted to split the parts into multiple configuration services. So my app.module.ts imports a custom config module
#Module({
imports: [CustomConfigModule]
})
export class AppModule {}
This custom config module (config.module.ts) bundles all the config services and loads the Nest config module
#Module({
imports: [ConfigModule.forRoot()],
providers: [ServerConfigService],
exports: [ServerConfigService],
})
export class CustomConfigModule {}
Lastly I have a simple config service server.config.service.ts which returns the port the application is running on
#Injectable()
export class ServerConfigService {
constructor(private readonly configService: ConfigService) {}
public get port(): number {
return this.configService.get<number>('SERVER_PORT');
}
}
I would like to validate those services on application startup. The docs explain how to setup a validationschema for the configuration module
https://docs.nestjs.com/techniques/configuration#schema-validation
How can I use that for my service validation when using a custom config module?
Do I have to call joi in each service constructor and validate the properties there?
Thanks in advance
I believe in your ConfigModule.forRoot() you can set the validation schema and tell Nest to run the validations on start up instead of having to add it to each custom config service. The docs show something like:
#Module({
imports: [
ConfigModule.forRoot({
validationSchema: Joi.object({
NODE_ENV: Joi.string()
.valid('development', 'production', 'test', 'provision')
.default('development'),
PORT: Joi.number().default(3000),
}),
validationOptions: {
allowUnknown: false,
abortEarly: true,
},
}),
],
})
export class AppModule {}
Which would run validations on NODE_ENV and PORT. You could of course extend it out to more validations overall. And then you could just have one ConfigModule that has smaller config services that split each segment up so all validations are run on startup and only what you need is available in each module's context.