NestJS - Nest can't resolve dependencies of the ConfigurationService (ConfigService, ?) - node.js

I am new to NestJs + Typescript, trying to initialize a project, after building it throws the following error:
ERROR [ExceptionHandler] Nest can't resolve dependencies of the ConfigurationService (ConfigService, ?). Please make sure that the argument CachingService at index [1] is available in the ConfigurationService context.
I tried many possible ways to solve this but no luck yet
These are the two modules in question:
import { CacheModule, Module } from '#nestjs/common';
import { CachingService } from './caching.service';
#Module({
imports: [
CacheModule.register({
ttl: 0,
}),
],
providers: [CachingService],
exports: [CachingService],
})
export class CachingModule {}
import { Module } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import { CachingModule } from '../caching/caching.module';
import { ConfigurationService } from './configuration.service';
import { config } from './environmentConfig/default.config';
import deploymentConfig from './deploymentConfig/config';
import { CachingService } from '../caching/caching.service';
#Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
load: [() => config, deploymentConfig],
}),
CachingModule,
],
providers: [ConfigurationService, CachingService],
exports: [ConfigurationService],
})
export class ConfigurationModule {}
This is the service where I am trying to use the cachingModule and the error is being thrown:
import { Injectable, Logger, OnModuleInit } from '#nestjs/common';
import { ConfigService } from '#nestjs/config';
import { CachingService } from '../caching/caching.service';
#Injectable()
export class ConfigurationService implements OnModuleInit {
private readonly logger = new Logger(ConfigurationService.name);
constructor(
private readonly configService: ConfigService,
private cachingService: CachingService,
) {}
How to fix this?

Remove the CachingService as a provider in the ConfigurationModule.

Related

TypeError: Cannot read properties of undefined when call method of injected provider in NestJS

Follow tutorial at here, I'm just implement simple NestJS app with a module have injected provider below:
# app.module.ts
import { Module } from '#nestjs/common'
import { ConfigModule } from '#nestjs/config'
import { AuthModule } from '#/modules/auth/auth.module'
#Module({
imports: [
ConfigModule.forRoot(),
AuthModule
]
})
export class AppModule {}
# auth.module.ts
import { Module } from '#nestjs/common'
import { AuthController } from '#/modules/auth/auth.controller'
import { AuthService } from '#/modules/auth/auth.service'
#Module({
controllers: [AuthController],
providers: [AuthService]
})
export class AuthModule {}
# auth.controller.ts
import { Controller, Get } from '#nestjs/common'
import { AuthService } from '#/modules/auth/auth.service'
#Controller('auth')
export class AuthController {
constructor (private readonly service: AuthService) {}
#Get('me')
public getSelfInfo (): string {
return this.service.getSelfInfo()
}
}
# auth.service.ts
import { Injectable } from '#nestjs/common'
#Injectable()
export class AuthService {
getSelfInfo (): string {
return 'ok'
}
}
But when call to endpoint, this error thrown:
[Nest] 17196 - 09/23/2022, 2:34:18 PM ERROR [ExceptionsHandler] Cannot read properties of undefined (reading 'getSelfInfo')
TypeError: Cannot read properties of undefined (reading 'getSelfInfo')
at AuthController.getSelfInfo (/dist/modules/auth/auth.controller.js:16:29)
Please tell me which problem at here.
Solved this issue when add code block below to app.controller.ts:
#Inject(AuthService)
private readonly service: AuthService
constructor (service: AuthService) {
this.service = service
}

How to add Bunyan logger in NestJs for logging

I am trying to add Bunyan logging library in my NestJs application. I am using nestjs bunyan official npm package which is npm i nestjs-bunyan but it's showing error when I am trying to instantiate inside service class. I am using its documentation and taken reference from here https://www.npmjs.com/package/nestjs-bunyan
Below is my code:
app.module.ts
import { Module } from '#nestjs/common';
import { BunyanLoggerModule } from 'nestjs-bunyan';
import { AppController } from './app.controller';
import { AppService } from './app.service';
#Module({
imports: [BunyanLoggerModule.forRoot({
isGlobal: true,
isEnableRequestLogger: true,
bunyan: {
name: 'MyApp',
},
}),],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
app.controller.ts
import { Controller, Get } from '#nestjs/common';
import { BunyanLoggerModule, ReqLogger } from 'nestjs-bunyan';
import { AppService } from './app.service';
#Controller()
export class AppController {
constructor(private readonly appService: AppService) {}
#ReqLogger() private readonly logger: BunyanLoggerModule
#Get()
getHello(): string {
return this.appService.getHello();
}
}
app.service.ts
import { Injectable, Logger } from '#nestjs/common';
import { BunyanLoggerModule } from 'nestjs-bunyan';
#Injectable()
export class AppService {
#Logger() private readonly logger: BunyanLoggerModule //Showing red line below #Logger()
getHello(): string {
return 'Hello World!';
}
}
How can I resolve this?
From the npm page it looks like that BunyanLoggerModule type should just be Bunyan, presumably from the bunyan package. Otherwise, you could call it Logger from #nestjs/common

NestJS Unable to Resolve Dependencies

I'm getting this error when I run my NestJS app.
[Nest] 19139 - 03/01/2020, 2:10:01 PM [ExceptionHandler] Nest can't resolve dependencies of the AccountsService (AccountRepository, ?, HashPasswordService). Please make sure that the argument Object at index [1] is available in the AccountsModule context.
Potential solutions:
- If Object is a provider, is it part of the current AccountsModule?
- If Object is exported from a separate #Module, is that module imported within AccountsModule?
#Module({
imports: [ /* the Module containing Object */ ]
})
+1ms
I am a bit confused what it causing this. As far as I can tell, my code looks correct. Here is the definition for my AccountsService class:
import { Injectable, ConflictException, Logger, InternalServerErrorException, NotFoundException, Inject } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { Account } from 'src/accounts/entities/account';
import { Repository, FindManyOptions, UpdateDateColumn } from 'typeorm';
import { CreateAccount } from 'src/accounts/dtos/create-account';
import { GetAccountsWithFilters } from 'src/accounts/dtos/get-accounts-with-filters';
import { UpdateAccountProfileInfo } from 'src/accounts/dtos/update-account-profile-info';
import { HashPasswordService } from '../hash-password/hash-password.service';
import { UpdateEmail } from 'src/accounts/dtos/update-email';
import { UpdatePhone } from 'src/accounts/dtos/update-phone';
import { AccountRepository } from 'src/accounts/repositories/account-repository';
/**
* AccountsService encapsulates all the actions that can be performed by an account.
*/
#Injectable()
export class AccountsService {
constructor(
#InjectRepository(AccountRepository) private accountRepository: AccountRepository,
private logger = new Logger("Accounts Service"),
#Inject(HashPasswordService)
private hashPasswordService: HashPasswordService,
) { }
// more code here
}
My Module looks like this.
import { Module } from '#nestjs/common';
import { AccountsService } from './services/accounts/accounts.service';
import { TypeOrmModule } from '#nestjs/typeorm';
import { Account } from './entities/account';
import { AccountsController } from './controllers/accounts/accounts.controller';
import { AccountCleanerService } from './services/account-cleaner/account-cleaner.service';
import { AuthenticationService } from './services/authentication/authentication.service';
import { AuthenticationController } from './controllers/authentication/authentication.controller';
import { HashPasswordService } from './services/hash-password/hash-password.service';
import { JwtModule } from "#nestjs/jwt";
import { PassportModule } from "#nestjs/passport";
import { JwtStrategy } from './auth-strategies/jwt-strategy';
import { AccountRepository } from './repositories/account-repository';
#Module({
imports: [
TypeOrmModule.forFeature([
Account,
AccountRepository,
]),
JwtModule.register({
secret: "SOME_APP_SECRET",
signOptions: {
expiresIn: 3600
}
}),
PassportModule.register({
defaultStrategy: "jwt",
}),
],
controllers: [
AccountsController,
AuthenticationController,
],
providers: [
AccountRepository,
HashPasswordService,
AccountsService,
AccountCleanerService,
AuthenticationService,
JwtStrategy,
],
exports: [JwtStrategy, PassportModule],
})
export class AccountsModule { }
Lastly, here is the App Module:
import { Module } from '#nestjs/common';
import { AccountsModule } from './accounts/accounts.module';
import { TypeOrmModule } from "#nestjs/typeorm";
import {Account} from "./accounts/entities/account";
import { ConfigModule } from "#nestjs/config";
import account from "./../config/account";
import auth from "./../config/auth";
import database from "./../config/database";
import server from "./../config/server";
import { AccountRepository } from './accounts/repositories/account-repository';
#Module({
imports: [
AccountsModule,
ConfigModule.forRoot({
// make this module available globally
isGlobal: true,
// The configuration files.
load: [
account,
auth,
database,
server
],
}),
TypeOrmModule.forRoot({
type: "mongodb",
url: "my connection string here",
entities: []
}),
],
controllers: [],
providers: [],
})
export class AppModule { }
As you can see, I have clearly made the services available to the module. So, I am kind of confused why Nest is unable to resolve the dependencies. Additionally, there should not be any other module right now, aside from the App module.,, which is also provided above. Any ideas why NestJS is throwing this error?
Nest is having trouble resolving the dependency of Logger, and as it is not provided in the providers array, it won't be able to resolve it. You've got three options:
1) Move the private logger = new Logger('Account Service') to the body of the constructor
2) Move the private logger = new Logger('Account Service') to the third position and mark it as #Optional() so that Nest doesn't throw an error when the value is unknown.
3) Add Logger to the providers array of AccountModule and then use the this.logger.setContext() method to properly set the context
The built in Logger class is #Injectable() so it is possible to use it through DI, but you have to ensure that it is provided just as any other provider is in the NestJS ecosystem.

How do I include a request scoped provider which needs an injected request in via an imported module

We are building up a mono-repo of microservices, and want to have some shared libraries which we import into various services.
Right now I am trying to build up a shared module which will have a provider which needs access to the request. Here is an example:
import { Injectable, Scope, Inject } from '#nestjs/common'
import { REQUEST } from '#nestjs/core'
import { Request } from 'express'
import { APILogger } from '#freebird/logger'
import { APIGatewayProxyEvent, Context } from 'aws-lambda'
export interface IAPIGatewayRequest extends Request {
apiGateway?: {
event?: APIGatewayProxyEvent
context?: Context
}
}
#Injectable({ scope: Scope.REQUEST })
export class RequestLogger extends APILogger {
constructor(#Inject(REQUEST) request: IAPIGatewayRequest) {
if (!request.apiGateway || !request.apiGateway.event || !request.apiGateway.context) {
throw new Error(
'You are trying to use the API Gateway logger without having used the aws-serverless-express middleware',
)
}
super(request.apiGateway.event, request.apiGateway.context)
}
}
I have been trying to bundle this as a module like so:
import { Module } from '#nestjs/common'
import { RequestLogger } from './logger'
#Module({
providers: [RequestLogger],
exports: [RequestLogger],
})
export class LambdaModule {}
And then import it into the main service module like this:
import { Module } from '#nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { LambdaModule } from '#freebird/nest-lambda'
#Module({
imports: [LambdaModule],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
However, when I do this I get an error:
Nest can't resolve dependencies of the RequestLogger (?). Please make
sure that the argument at index [0] is available in the AppModule
context.
But when I pull the RequestLogger provider into the service module, and include it like this I get no errors:
import { Module } from '#nestjs/common'
import { AppController } from './app.controller'
import { AppService } from './app.service'
import { RequestLogger } from './logger'
#Module({
controllers: [AppController],
providers: [AppService, RequestLogger],
})
export class AppModule {}
I discovered the problem. In my case I had slightly different requirements between my library package and the service package. So different versions of nest were in play. This apparently causes conflicts.

Nest can't resolve dependencies of the ICommandBusAdapter

Trying to use my ICommandBusAdapter.ts in my CreateUserAction.ts, but I get the following error:
[ExceptionHandler] Nest can't resolve dependencies of the ICommandBusAdapter (?). Please make sure that the argument at index [0] is available in the AdapterModule context
I have created a AdapterModule that will share all providers to others modules, but it doesn't seems work.
Any idea ?
AppModule.ts
import { UserModule } from './User/UserModule';
import { AdapterModule } from './Common/AdapterModule';
#Module({
imports: [AdapterModule, UserModule, // ...],
})
export class AppModule {}
AdapterModule.ts
import { CommandBusAdapter } from 'src/Infrastructure/Adapter/Bus/CommandBusAdapter';
const providers = [
{ provide: 'ICommandBusAdapter', useClass: CommandBusAdapter },
// ...
];
#Module({
providers: [...providers],
exports: [...providers],
})
export class AdapterModule {}
UserModule.ts
import { Module } from '#nestjs/common';
import { CreateUserAction } from 'src/Infrastructure/Action/User/CreateUserAction';
#Module({
controllers: [CreateUserAction],
})
export class UserModule {}
CommandBusAdapter.ts
import { CommandBus, ICommand } from '#nestjs/cqrs';
import { ICommandBusAdapter } from 'src/Application/Adapter/Bus/ICommandBusAdapter';
#Injectable()
export class CommandBusAdapter implements ICommandBusAdapter {
constructor(private readonly commandBus: CommandBus) {}
execute = (command: ICommand) => {
return this.commandBus.execute(command);
};
}
CreateUserAction.ts
import { ICommandBusAdapter } from 'src/Application/Adapter/Bus/ICommandBusAdapter';
export class CreateUserAction {
constructor(
#Inject('ICommandBusAdapter')
private readonly commandBus: ICommandBusAdapter,
) {}
// ...
Did you remember to add the CqrsModule to your application?
import { CqrsModule } from '#nestjs/cqrs';
#Module({
imports: [CqrsModule]
....
Without it there won't anything providing the CommandBus which you're trying to inject.
You can see an example here:
https://github.com/kamilmysliwiec/nest-cqrs-example/blob/master/src/heroes/heroes.module.ts

Resources