NestJS can't resolve dependency - nestjs

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.

Related

Unclear error message "Nest can't resolve dependencies of the XXXController (?) <...>" in NestJS

The part after (?) of error message is unclear:
Error: Nest can't resolve dependencies of the MemberController (?).
Please make sure that the argument Object at index [0] is available in
the MemberModule context.
Potential solutions:
If Object is a provider, is it part of the current MemberModule?
If Object is exported from a separate #Module, is that module imported within MemberModule? #Module({
imports: [ /* the Module containing Object */ ] })
Here the incomprehensible moments are:
Object is a broad concept; I can't understand on what it refers
Object at index [0] - at index of what?
MemberModule context - again, the context is a broad concept. Is context the property of some object?
If Object is a provider, is it part of the current MemberModule? - what means the difference between "part of" and "not part of"?
Main module
#NestJS_Module({
imports: [
MemberModule,
TypeOrmModule.forRoot({
type: "postgres",
host: "localhost",
port: 5432,
username: "*******",
password: "*******",
database: "*******",
autoLoadEntities: true,
synchronize: __IS_DEVELOPMENT_BUILDING_MODE__
})
],
controllers: [],
providers: []
})
export default class NestJS_Application {}
Member module
import { Module as NestJS_Module } from "#nestjs/common";
import { TypeOrmModule } from "#nestjs/typeorm";
import MemberModel from "../Data/FromDataBase/Models/Member.model";
import MemberController from "../Controllers/Member.controller";
import MemberTypeORM_Gateway from "../Data/FromDataBase/Gateways/MemberTypeORM_Gateway";
#NestJS_Module({
imports: [ TypeOrmModule.forFeature([ MemberModel ]) ],
controllers: [ MemberController ],
providers: [ MemberTypeORM_Gateway ]
})
export default class MemberModule {}
Member controller
#Controller()
export default class MemberController {
private readonly memberService: MemberGateway;
public constructor(applicationService: MemberGateway) {
this.memberService = applicationService;
}
// ...
}
Because I tried tried the solution for Nest can't resolve dependencies of the PhotoService (?), here must the other solution.

NestJs can't resolve service dependencies on a circular dependency

i have the problem that i have a circular dependency in my project. Unfortunately I cannot solve this with forwardRef.
The following structure:
OrderModule
OrderService
I have the following dependencies in the orderService
PriceService
CustomerService
SalePriceService
...
PriceModule
PriceService
I have the following dependencies in the priceService
OrderService
ProductService
...
I've tried all the options from the Official Documentation.
docs NestJs circular-dependency
What has to be considered here if there are more dependencies in a service?
Many thanks. Best regards.
Update:
order.module.ts
#Module({
imports: [
CustomerModule,
ProductModule,
MongooseModule.forFeature([{ name: 'Order', schema: OrderSchema }]),
forwardRef(() => PriceModule),
],
controllers: [OrderController],
providers: [OrderService],
exports: [OrderService],
})
export class OrderModule {}
order.service.ts
#Injectable()
export class OrderService extends GenericCrudService<OrderDocument> {
constructor(
#InjectModel(Order.name) readonly order: Model<OrderDocument>,
private readonly productService: ProductService,
#Inject(forwardRef(() => PriceService))
private readonly priceService: PriceService,
) {
super(order);
}
}
price.module.ts
#Module({
imports: [
CustomerModule,
SalePriceModule,
MongooseModule.forFeature([{ name: 'Price', schema: PriceSchema }]),
forwardRef(() => OrderModule),
],
controllers: [],
providers: [PriceService],
exports: [PriceService],
})
export class PriceModule {}
price.service.ts
#Injectable()
export class PriceService extends GenericCrudService<PriceDocument> {
constructor(
#InjectModel(Price.name) readonly price: Model<PriceDocument>,
private readonly customerService: CustomerService,
private readonly salePriceService: SalePriceService,
#Inject(forwardRef(() => OrderService))
private readonly orderService: OrderService,
) {
super(price);
}
}
product.module.ts
#Module({
imports: [
PriceModule,
MongooseModule.forFeature([{ name: 'Product', schema: ProductSchema }]),
],
controllers: [ProductController],
providers: [ProductService],
exports: [ProductService],
})
export class ProductModule {}
product.service.ts
#Injectable()
export class ProductService extends GenericCrudService<ProductDocument> {
constructor(
#InjectModel(Product.name) readonly product: Model<ProductDocument>,
) {
super(product);
}
}
The error I'm getting is:
The module at index [1] of the OrderModule "imports" array is undefined.
Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [1] is of type "undefined". Check your import statements and the type of the module.
Scope [AppModule -> ProductModule -> PriceModule]
Error: Nest cannot create the OrderModule instance.
The module at index [1] of the OrderModule "imports" array is undefined.
Potential causes:
- A circular dependency between modules. Use forwardRef() to avoid it. Read more: https://docs.nestjs.com/fundamentals/circular-dependency
- The module at index [1] is of type "undefined". Check your import statements and the type of the module.
Scope [AppModule -> ProductModule -> PriceModule]
So there's the obvious circular dependency that you have here: OrdersModule to PricesModule and back, that one is properly forwardReffed. However, there's another, not so obvious circular dependency too. OrdersModule to ProductsModule to PricesModule because the next import would be OrdersModule. Because of this, OrdersModule needs to forwardRef the ProductsModule and ProductsModule needs to forwardRef the PricesModule. It looks like the services themselves aren't circular, so it's just the modules that need the forward ref. Always make sure to check the entire import chain, especially when Nest is trying to report something like it did with Scope [AppModule -> ProductModule -> PriceModule].

How to create service with Repository exports?

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.

Nest can't resolve dependencies of RabbitMQService service

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'm getting following "Nest can't resolve dependencies of the WorkspaceController..." error in nest.js

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

Resources