Nest can't resolve dependencies of the CommonModule - javascript

I'm new in NEST.js world, and I trying to create simple middleware.
First, I created a middleware with this command:
nest g middleware common/middleware/logging
And after I add my code
import { Injectable, NestMiddleware } from '#nestjs/common';
#Injectable()
export class LoggingMiddleware implements NestMiddleware {
use(req: any, res: any, next: () => void) {
console.time('Request-response time');
console.log('Hi from middleware!');
res.on('finish', () => console.timeEnd('Request-response time'));
next();
}
}
And finally, I add the middleware
import { Module, MiddlewareConsumer } from '#nestjs/common';
import { APP_GUARD } from '#nestjs/core';
import { ApiKeyGuard } from './guards/api-key.guard';
import { ConfigModule } from '#nestjs/config';
import { LoggingMiddleware } from './middleware/logging.middleware';
#Module({
imports: [
ConfigModule
],
providers: [
{
provide: APP_GUARD,
useClass: ApiKeyGuard
}
]
})
export class CommonModule {
constructor(consumer: MiddlewareConsumer) {
consumer.apply(LoggingMiddleware).forRoutes('*')
}
}
But when i try to run it:
Nest can't resolve dependencies of the CommonModule (?). Please make
sure that the argument Object at index [0] is available in the
CommonModule context.
Potential solutions:
If Object is a provider, is it part of the current CommonModule?
If Object is exported from a separate #Module, is that module imported within CommonModule? #Module({
imports: [ /* the Module containing Object */ ] }) +2ms Error: Nest can't resolve dependencies of the CommonModule (?). Please make
sure that the argument Object at index [0] is available in the
CommonModule context.
Potential solutions:
If Object is a provider, is it part of the current CommonModule?
If Object is exported from a separate #Module, is that module imported within CommonModule? #Module({
imports: [ /* the Module containing Object */ ] })
Can you help me?

The MiddlewareConsumer isn't a part of the constructor. Rather, your module class should implement NestModule and should have a configure method that takes in the consumer: MiddlewareConsumer as the first and only paramter.
#Module({
imports: [
ConfigModule
],
providers: [
{
provide: APP_GUARD,
useClass: ApiKeyGuard
}
]
})
export class CommonModule implmenets NestModule {
configure(consumer: MidlewareConsumer) {
consumer.apply(LoggingMiddleware).forRoutes('*')
}
}

Related

Error: Nest can't resolve dependencies of the CanModifyGuard (UsersService, ?)

just when I thought I do understand how the modules work and starting to play with guards which leads me to this error in full
Error: Nest can't resolve dependencies of the CanModifyGuard (UsersService, ?). Please make sure that the argument TelevisionsService at index [1] is available in the UsersModule context.
Potential solutions:
- If TelevisionsService is a provider, is it part of the current UsersModule?
- If TelevisionsService is exported from a separate #Module, is that module imported within UsersModule?
#Module({
imports: [ /* the Module containing TelevisionsService */ ]
})
CanModifyGuard was fine when the guard is using only TelevisionsService, once I added the UsersService and add the guard into the UsersController
The error above popped up.
Wonder if I can have another pair of eyes where I am setting this wrong?
app.module.ts
import { MiddlewareConsumer, Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '#nestjs/mongoose';
import { ConfigModule } from '#nestjs/config';
import { UsersModule } from './resources/users/users.module';
import { AuthModule } from './resources/auth/auth.module';
import { CommonModule } from './resources/common/common.module';
import { TelevisionsModule } from './resources/televisions/televisions.module';
import { CurrentUserMiddleware } from './common/middlewares/current-user.middleware';
#Module({
imports: [
ConfigModule.forRoot(),
MongooseModule.forRoot(process.env.DATABASE_URL),
UsersModule,
AuthModule,
CommonModule,
TelevisionsModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {
configure(consumer: MiddlewareConsumer) {
consumer.apply(CurrentUserMiddleware).forRoutes('*');
}
}
can-modify.guard.ts
import {
CanActivate,
ExecutionContext,
Injectable,
UnauthorizedException,
} from '#nestjs/common';
import { TelevisionsService } from '../../resources/televisions/televisions.service';
import { UsersService } from '../../resources/users/users.service';
#Injectable()
export class CanModifyGuard implements CanActivate {
constructor(
private readonly usersService: UsersService,
private readonly televisionsService: TelevisionsService,
) {}
async canActivate(context: ExecutionContext): Promise<boolean> {
//logics here
}
}
users.module.ts
import { Module } from '#nestjs/common';
import { UsersController } from './users.controller';
import { UsersService } from './users.service';
import { MongooseModule } from '#nestjs/mongoose';
import { User, UserSchema } from './user.entity';
#Module({
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
],
exports: [UsersService],
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}
televisions.module.ts
import { Module } from '#nestjs/common';
import { TelevisionsController } from './televisions.controller';
import { TelevisionsService } from './televisions.service';
import { MongooseModule } from '#nestjs/mongoose';
import { Television, TelevisionSchema } from './television.entity';
import { UsersModule } from '../users/users.module';
#Module({
imports: [
MongooseModule.forFeature([
{ name: Television.name, schema: TelevisionSchema },
]),
UsersModule,
],
exports: [TelevisionsService],
controllers: [TelevisionsController],
providers: [TelevisionsService],
})
export class TelevisionsModule {}
auth.module.ts
import { Module } from '#nestjs/common';
import { AuthService } from './auth.service';
import { AuthController } from './auth.controller';
import { UsersModule } from '../users/users.module';
import { ConfigModule } from '#nestjs/config';
import authConfig from './config/auth.config';
#Module({
imports: [UsersModule, ConfigModule.forFeature(authConfig)],
controllers: [AuthController],
providers: [AuthService],
})
export class AuthModule {}
common.module.ts (dont think this file would have any effect but just in case)
import { Module } from '#nestjs/common';
import { APP_GUARD } from '#nestjs/core';
import { AuthorizationRolesGuard } from '../../common/guards/authorization-roles.guard';
#Module({
providers: [
{
provide: APP_GUARD,
useClass: AuthorizationRolesGuard,
},
],
})
export class CommonModule {}
In order to use the guard, I added the guard to the specific route #UseGuards(CanModifyGuard) and again, it is working fine when I added this guard into television controller but once I added it to user controller the error pops up.
As the error mentioned for potential solutions even though UsersModule is not using any of the TelevisionsService I still imported TelevisionsModule into UsersModule but no luck on getting this fix...and instead I would get another error and said potential cause A circular dependency between modules. Use forwardRef() to avoid it. I read the doc about it and also tried using forwardRef() but still didn't fix it. I might have put the forwardRef() in the wrong place because I am not sure where I should use it.
Thank you in advance for any suggestions or advices.
If I'm understanding your set up correctly, you have a circular dependency on the modules, so you need to forwardRef the imports for those. Using these modules should fix your issue:
user.module.ts
#Module({
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
forwardRef(() => TelvisionsModule),
],
exports: [UsersService],
controllers: [UsersController],
providers: [UsersService],
})
export class UsersModule {}
televisons.module.ts
#Module({
imports: [
MongooseModule.forFeature([
{ name: Television.name, schema: TelevisionSchema },
]),
forwardRef(() => UsersModule),
],
exports: [TelevisionsService],
controllers: [TelevisionsController],
providers: [TelevisionsService],
})
export class TelevisionsModule {}

NestJs cannot istantiate module (circular dependencies error?)

I have two modules which depend on each other.
GameModule.ts
import { Module, CacheModule, Global } from '#nestjs/common';
import { GameController } from './game.controller';
import { GameService } from './game.service';
import { PlayerModule } from '#src/player/player.module';
#Global()
#Module({
imports: [
CacheModule.register(),
PlayerModule,
],
controllers: [GameController],
providers: [GameService],
exports: [CacheModule, GameService],
})
export class GameModule {}
PlayerModule.ts
import { Module, Global } from '#nestjs/common';
import { PlayerController } from './player.controller';
import { PlayerService } from './player.service';
import { GameModule } from '#src/game/game.module';
import { Web3ManagerModule } from '#src/web3-manager/web3-manager.module';
#Global()
#Module({
imports: [GameModule, Web3ManagerModule],
controllers: [PlayerController],
providers: [PlayerService],
exports: [PlayerService],
})
export class PlayerModule {}
I defined in their services the other one with forwardRef
GameService.ts
...
constructor(
#Inject(CACHE_MANAGER) private cacheManager: Cache,
#Inject(forwardRef(() => PlayerService))
private playerService: PlayerService,
) {
...
PlayerService.ts
...
constructor(
#Inject(forwardRef(() => GameService))
private gameService: GameService,
private web3Manager: Web3ManagerService,
) {
...
but I keep getting the error:
Nest cannot create the GameModule instance.
The module at index [1] of the GameModule "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.
What am I missing?

Nest can't resolve dependencies of the JwtService

I have created some modules here but i am facing an error
Auth module
import { Module } from "#nestjs/common";
import { AuthService } from "./auth.service";
import { LocalStrategy } from "./local.strategy";
import { JwtStrategy } from "./jwt.strategy";
import { UsersModule } from "../users/users.module";
import { PassportModule } from "#nestjs/passport";
import { JwtModule, JwtService } from "#nestjs/jwt";
import { jwtConstants } from "./constants";
import { ConfigModule, ConfigService } from "#nestjs/config";
#Module({
imports: [
UsersModule,
PassportModule,
JwtModule.register({
secret: jwtConstants.secret,
signOptions: { expiresIn: "1d" },
}),
],
providers: [AuthService, LocalStrategy, JwtStrategy],
exports: [AuthService, LocalStrategy, JwtStrategy],
})
export class AuthModule {}
Email module
import { Module } from "#nestjs/common";
import EmailService from "./email.service";
import { ConfigModule } from "#nestjs/config";
import { EmailConfirmationService } from "./emailConfirmation.service";
import { EmailConfirmationController } from "./emailConfirmation.controller";
import { EmailConfirmationGuard } from "./guards/emailConfirmation.guard";
import { AuthModule } from "src/auth/auth.module";
import { UsersModule } from "src/users/users.module";
#Module({
imports: [ConfigModule,AuthModule,UsersModule],
providers: [EmailService,EmailConfirmationService,EmailConfirmationGuard],
exports: [EmailConfirmationService,EmailConfirmationGuard],
controllers : [EmailConfirmationController]
})
export class EmailModule {}
User module
import { Module } from "#nestjs/common";
import { UsersService } from "./users.service";
import { UsersController } from "./users.controller";
import { MongooseModule } from "#nestjs/mongoose";
import { UserSchema } from "./entities/user.entity";
import { EmailModule } from "src/email/email.module";
#Module({
imports: [MongooseModule.forFeature([{ name: "User", schema: UserSchema }]),EmailModule],
providers: [UsersService],
exports: [UsersService],
controllers: [UsersController],
})
export class UsersModule {}
Error I am facing
[Nest] 9200 - 09/26/2021, 3:43:15 PM ERROR [ExceptionHandler] Nest cannot create the EmailModule instance.
The module at index [1] of the EmailModule "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 -> AuthModule -> UsersModule]
Error: Nest cannot create the EmailModule instance.
The module at index [1] of the EmailModule "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.
What am i missing ?
EmailConfirmationService is used in UsersController
UserService is used in EmailConfirmationService
You have JwtService listed in your imports. Imports are for modules only.
Share the code from JwtService as well so that we can make sure there are no other issues.
Update:
If the EmailModule wants to use the exports from the AuthModule (JwtService in this case), it must add the AuthModule to its imports array.
This is the entire premise of the DI system, modules share things between eachother by placing the thing they intend to share in the exports array. After that, any module can add the Source module to its imports array to gain access to the things that the source exported. The error message literally spells it out for you:
If JwtService is exported from a separate #Module, is that module imported within EmailModule? #Module({ imports: [ /* the Module containing JwtService */ ] })
In order to use EmailService in you UserController and also UserService is used in EmailConfirmationService then you have to do something like this in UserModule:
imports: [forwardRef(() => EmailModule)]
and inside the EmailModule do the same thing for the UserModule:
imports: [forwardRef(() => UserModule)]
Rest of the imports should be without the forwardRef(()=>)
you can read more about circular dependency here https://docs.nestjs.com/fundamentals/circular-dependency
Make sure your target in tsconfig.json is es6.

NestJS - JWTModule context dependency

After run my app i get this...
[Nest] 5608 - 01.01.2021, 18:12:05 [ExceptionHandler] Nest can't resolve dependencies of the JwtService (?). Please make sure that the argument JWT_MODULE_OPTIONS at index [0] is available in the JwtModule context.
Potential solutions:
- If JWT_MODULE_OPTIONS is a provider, is it part of the current JwtModule?
- If JWT_MODULE_OPTIONS is exported from a separate #Module, is that module imported within JwtModule?
#Module({
imports: [ /* the Module containing JWT_MODULE_OPTIONS */ ]
})
can someone tell me what i have wrong with my code?
#Module({
imports: [TypeOrmModule.forFeature([User]),
JwtModule.register({
secretOrPrivateKey: 'secret12356789'
})
],
providers: [UserService]
})
export class AuthModule { }
#Module({
imports: [
TypeOrmModule.forRoot({
//
}),
AuthModule,
UserModule,
JwtModule
],
controllers: [AppController, UserController, AuthController ],
providers: [AppService, UserService, AuthService ],
})
export class AppModule {}
thanks for any help
///////////////////////////////////////////////////////////////
In your AppModule you have the JwtModule imported but adding no options to it. This is what's causing the issue. As you already have the JwtModule registered in the AuthModule, this probably isn't what you're meaning to do.
You have the UserService registered in at least two places (AuthModule and AppModule), you're probably meaning to add the UserService to the exports of UserModule and then add the UserModule to the imports array of the module where you need the UserService.
TL;DR See, copy/paste examples.
Recently had the same issue.
As Nest.JS recommends the JwtModule could be declared in an authorization module: https://docs.nestjs.com/security/authentication. And, yes, it should be declared once with all its settings. The topic message could come from a multiple declaration (some of them has no JWT_MODULE_OPTIONS). Can wrap Jay's response with a prepared working example.
So the auth module should look like:
//./authorization/authorization.module.ts
import { Module } from '#nestjs/common';
import { JwtModule } from '#nestjs/jwt';
import { AuthorizationController } from './authorization.controller';
import { AuthorizationService } from './authorization.service';
#Module({
imports: [
...
JwtModule.register({
secret: process.env.ACCESS_TOKEN_SECRET || 'SOME_SECURE_SECRET_jU^7',
signOptions: {
expiresIn: process.env.TOKEN_EXPIRATION_TIME || '24h',
}
}),
....
],
controllers: [AuthorizationController],
providers: [AuthorizationService],
exports: [AuthorizationService, JwtModule]//<--here exports JwtModule
//as a part of AuthorizationModule
})
export class AuthorizationModule {};
Then your AppModule will inject the exported JwtModule from AuthorizationModule in this way.
//./app.module.js
import { Module } from '#nestjs/common';
import { AuthorizationModule } from './authorization/authorization.module';
#Module({
imports: [
...
AuthorizationModule, //<-- here injects the set up JwtModule
//NB! No additional injections required!
...
],
...
})
export class AppModule {};
Hope, this will help. ;)

Nest can't resolve dependencies of custom service

I am basically follow this tutorial with very minor modifications:link
I am using nest 6.14.2 on node 12.10.0.
When running my app I get:
> recon-backend#0.0.1 start C:\Users\e5553079\Desktop\Node_Projects\recon-backend
> nest start
[Nest] 8324 - 02/10/2020, 9:28:21 AM [NestFactory] Starting Nest application...
[Nest] 8324 - 02/10/2020, 9:28:21 AM [InstanceLoader] MongooseModule dependencies initialized +53ms
[Nest] 8324 - 02/10/2020, 9:28:21 AM [ExceptionHandler] Nest can't resolve dependencies of the ReconQueryService (?). Please make sure that the argument ReconQueryModel at index [0] is available in the AppModule context.
Potential solutions:
- If ReconQueryModel is a provider, is it part of the current AppModule?
- If ReconQueryModel is exported from a separate #Module, is that module imported within AppModule?
#Module({
imports: [ /* the Module containing ReconQueryModel */ ]
})
+2ms
Error: Nest can't resolve dependencies of the ReconQueryService (?). Please make sure that the argument ReconQueryModel at index [0] is available in the AppModule context.
My files look like this:
1. app.module.ts
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '#nestjs/mongoose';
import { ReconQueryModule } from './reconQuery/reconQuery.module';
import { ReconQueryService } from './reconQuery/reconQuery.service';
import { ReconQueryController } from './reconQuery/reconQuery.controller';
#Module({
imports: [
MongooseModule.forRoot('mongodb://localhost/backend-app', { useNewUrlParser: true }),
ReconQueryModule
],
controllers: [AppController, ReconQueryController],
providers: [AppService, ReconQueryService],
})
export class AppModule {}
2. reconQuery.service.ts
import { Injectable } from '#nestjs/common';
import { Model } from 'mongoose';
import { InjectModel } from '#nestjs/mongoose';
import { ReconQuery } from './interfaces/reconQuery.interface';
import { CreateReconQueryDTO } from './dto/create-reconQuery.dto';
#Injectable()
export class ReconQueryService {
constructor(#InjectModel('ReconQuery') private readonly reconQueryModel: Model<ReconQuery>) { }
// Fetch all queries
async getAllQueries(): Promise<ReconQuery[]> {
const queries = await this.reconQueryModel.find().exec();
return queries;
}
...
3. reconQuery.interface.ts
import { Document } from 'mongoose';
export interface ReconQuery extends Document {
readonly id: number;
readonly name: string;
readonly sql: string;
}
4. reconQuery.module.ts
import { Module } from '#nestjs/common';
import { ReconQueryController } from './reconQuery.controller';
import { ReconQueryService } from './reconQuery.service';
import { MongooseModule } from '#nestjs/mongoose';
import { ReconQuerySchema } from './schemas/reconQuery.schema';
#Module({
imports: [
MongooseModule.forFeature([{ name: 'ReconQuery', schema: ReconQuerySchema }])
],
controllers: [ReconQueryController],
providers: [ReconQueryService]
})
export class ReconQueryModule {}
I wonder why it cries about ReconQueryModel as I do not have such an entity, just a ReconQuery interface.
You have extra ReconQueryService provided in AppModule.
import { Module } from '#nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { MongooseModule } from '#nestjs/mongoose';
import { ReconQueryModule } from './reconQuery/reconQuery.module';
import { ReconQueryService } from './reconQuery/reconQuery.service';
import { ReconQueryController } from './reconQuery/reconQuery.controller';
#Module({
imports: [
MongooseModule.forRoot('mongodb://localhost/backend-app', { useNewUrlParser: true }),
ReconQueryModule
],
controllers: [AppController, ReconQueryController],
providers: [AppService, ReconQueryService], // <-- this causes the error
})
export class AppModule {}
#InjectModel() is provided by calling MongooseModule.forFeature(...) on a certain #Module(). ReconQueryService in ReconQueryModule is fine because that's where you have MongooseModule.forFeature() called so #InjectModel() is provided properly. However, in AppModule, you don't have MongooseModule.forFeature() so Nest cannot resolve the #InjectModel() for ReconQueryService.
Check if you really need to use ReconQueryService in AppModule (services and controllers declared in AppModule). If you don't, then remove ReconQueryService from providers array. If you do, then go to ReconQueryModule and do the following:
import { Module } from '#nestjs/common';
import { ReconQueryController } from './reconQuery.controller';
import { ReconQueryService } from './reconQuery.service';
import { MongooseModule } from '#nestjs/mongoose';
import { ReconQuerySchema } from './schemas/reconQuery.schema';
#Module({
imports: [
MongooseModule.forFeature([{ name: 'ReconQuery', schema: ReconQuerySchema }])
],
controllers: [ReconQueryController],
providers: [ReconQueryService],
exports: [ReconQueryService] // <-- add this line
})
export class ReconQueryModule {}
exported things will be available to use outside of the module they're provided in. Just import that module somewhere else.

Categories