Nest can't resolve dependencies of custom service - javascript

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.

Related

Nest can't resolve dependencies in my project

the console says :
Nest can't resolve dependencies of the VisitService (?, DonorService). Please make sure that the argument VisitModel at index [0] is available in the VisitModule context.
Potential solutions:
If VisitModel is a provider, is it part of the current VisitModule?
If VisitModel is exported from a separate #Module, is that module imported within VisitModule?
this is vistit.service :
import { forwardRef, Inject, Injectable } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { Model } from 'mongoose';
import { DonorVisitStatus } from 'src/constants/donor-visit-status.enum';
import { GetDateDifferenceHours } from 'src/utils';
import { DonorService } from '../donor/donor.service';
import { VisitDocument } from '../schemas/visit.schema';
import { CreateVisitInput } from './graphql/visit.input';
import { Visit } from './graphql/visit.type';
#Injectable()
export class VisitService {
constructor(
#InjectModel('Visit') private readonly visitModel: Model<VisitDocument>,
#Inject(forwardRef(() => DonorService)) private donorService: DonorService,
) {}
async findVisitById(visitId: string): Promise<VisitDocument | undefined> {
const visit = await this.visitModel
.findOne({ _id: visitId })
.populate('medicalCheckup')
.populate('phlebotomy')
.populate('donor');
return visit || undefined;
}
}
visit.module :
import { Module, forwardRef } from '#nestjs/common';
import { VisitService } from './visit.service';
import { VisitResolver } from './visit.resolver';
import { ConfigModule } from 'config/config.module';
import { MongooseModule } from '#nestjs/mongoose';
import { VisitSchema } from '../schemas/visit.schema';
import { DonorModule } from '../donor/donor.module';
#Module({
imports: [
MongooseModule.forFeature([{ name: 'Visit', schema: VisitSchema }], 'aidea_donation'),
ConfigModule,
forwardRef(() => DonorModule),
],
providers: [VisitService, VisitResolver],
exports: [VisitService],
})
export class VisitModule {}
i have checked it alot but i can't find any error
You use a named connection in MongooseModule.forFeature() so you need to use the same connection in the #InjectModel(). Change your #InjectModel() to #InjectModel('Visit', 'aidea_donation') and it should work

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 UsersService (UserModel, ?)

my user.module.ts:
import { forwardRef, Module } from '#nestjs/common';
import { UsersService } from './users.service';
import { UsersController } from './users.controller';
import { UserSchema } from './schemas/user.schema';
import { MongooseModule } from '#nestjs/mongoose';
import { AuthModule } from 'src/auth/auth.module';
#Module({
imports: [MongooseModule.forFeature([{name: 'User', schema: UserSchema}]),AuthModule],
controllers: [UsersController],
providers: [UsersService],
exports: [UsersService]
})
export class UsersModule {}
my auth.module.ts
import { forwardRef, Module } from '#nestjs/common';
import { AuthService } from './auth.service';
import { UsersModule } from '../users/users.module';
import { PassportModule } from '#nestjs/passport';
import { LocalStrategy } from './local.strategy';
#Module({
imports: [forwardRef(() => UsersModule), PassportModule],
providers: [AuthService, LocalStrategy],
})
export class AuthModule {}
my app.module.ts
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UsersModule } from './users/users.module';
#Module({
imports: [UsersModule,MongooseModule.forRoot('mongodb://localhost:27017/nest1')],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
this are giving me error:
[12:55:42 pm] Found 0 errors. Watching for file changes.
[Nest] 15944 - 20/09/2021, 12:55:45 pm LOG [NestFactory] Starting
Nest application... [Nest] 15944 - 20/09/2021, 12:55:45 pm LOG
[InstanceLoader] MongooseModule dependencies initialized +126ms [Nest]
15944 - 20/09/2021, 12:55:46 pm ERROR [ExceptionHandler] Nest can't
resolve dependencies of the UsersService (UserModel, ?). Please make
sure that the argument AuthService at index [1] is available in the
UsersModule context.
Potential solutions:
If AuthService is a provider, is it part of the current UsersModule?
If AuthService is exported from a separate #Module, is that module imported within UsersModule? #Module({
imports: [ /* the Module containing AuthService */ ] })
Error: Nest can't resolve dependencies of the UsersService (UserModel,
?). Please make sure that the argument AuthService at index [1] is
available in the UsersModule context.
Potential solutions:
If AuthService is a provider, is it part of the current UsersModule?
If AuthService is exported from a separate #Module, is that module imported within UsersModule? #Module({
imports: [ /* the Module containing AuthService */ ] })
at Injector.lookupComponentInParentModules (C:\Users\Asus\Desktop\BILDEMP\ems-by-nestjs\employee-management-system\node_modules#nestjs\core\injector\injector.js:193:19)
at Injector.resolveComponentInstance (C:\Users\Asus\Desktop\BILDEMP\ems-by-nestjs\employee-management-system\node_modules#nestjs\core\injector\injector.js:149:33)
at resolveParam (C:\Users\Asus\Desktop\BILDEMP\ems-by-nestjs\employee-management-system\node_modules#nestjs\core\injector\injector.js:103:38)
at async Promise.all (index 1)
at Injector.resolveConstructorParams (C:\Users\Asus\Desktop\BILDEMP\ems-by-nestjs\employee-management-system\node_modules#nestjs\core\injector\injector.js:118:27)
at Injector.loadInstance (C:\Users\Asus\Desktop\BILDEMP\ems-by-nestjs\employee-management-system\node_modules#nestjs\core\injector\injector.js:47:9)
at Injector.loadProvider (C:\Users\Asus\Desktop\BILDEMP\ems-by-nestjs\employee-management-system\node_modules#nestjs\core\injector\injector.js:69:9)
at async Promise.all (index 3)
at InstanceLoader.createInstancesOfProviders (C:\Users\Asus\Desktop\BILDEMP\ems-by-nestjs\employee-management-system\node_modules#nestjs\core\injector\instance-loader.js:44:9)
at C:\Users\Asus\Desktop\BILDEMP\ems-by-nestjs\employee-management-system\node_modules#nestjs\core\injector\instance-loader.js:29:13
I'm going to make some assumptions about your service constructors, as you haven't provided those:
You have what looks to be a circular reference between the UserModule and the AuthModule. Because of this, in the imports of each module you need to use forwardRef of the module you're importing.
#Module({
imports: [forwardRef(() => UserModule), ...rest],
providers,
controllers,
exports
})
export class AuthModule {}
#Module({
imports: [forwardRef(() => AuthModule), ...rest],
providers,
controllers,
exports
})
export class UserModule {}
And speaking of exports above, you need to export a provider if you plan to use it outside of the module where it is in the providers (e.g. to use AuthService inside of UserService, the AuthModule needs to have providers: [AuthService] and exports: [AuthService]. This makes the provider available elsewhere.
Now, to make use of circular dependencies inside of the services, you also need to make use of forwardRef. In this case it will look like #Inject(forwardRef(() => OtherClass)) private readonly other: OtherClass, so you'd have something like
#Injectable()
export class UserService {
constructor(
#Inject(forwardRef(() => AuthService)) private readonly auth: AuthService,
private readonly dep2: DependencyClass2
) {}
// rest of values
}
You'll do the same thing in the AuthService but replacing AuthService in the #Inject() with UserService.
You need to import all the dependencies of UserService in UserModule. If you still can't figure out then please also add your user.service.ts file in the question.
You have to export the auth service in the authmodule in order to be able to inject it in the user service.

NestJS Dependency Injection Error: provider/module is not part of currently processed module

I've just started with NestJS and I'm wondering what the best way to solve this error is
Nest cannot export a provider/module that is not a part of the
currently processed module (UsersModule). Please verify whether the
exported UsersService is available in this particular context.
I am following along with the documentation here and I seem to have hit a brick wall. My app won't compile so I can't test any further. I'll add some of the files as examples.
auth.module.ts
import { Module } from '#nestjs/common';
import { UsersModule } from 'src/users/users.module';
import { AuthController } from './controllers/auth/auth.controller';
import { AuthService } from './services/auth/auth.service';
#Module({
imports: [UsersModule],
controllers: [AuthController],
providers: [AuthService],
exports: [AuthService],
})
export class AuthModule {}
users.module.ts
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { UsersController } from './controllers/users/users.controller';
import { User, UserSchema } from './schemas/user.schema';
import { UsersService } from './services/users/users.service';
#Module({
imports: [
MongooseModule.forFeature([{ name: User.name, schema: UserSchema }]),
],
controllers: [UsersController],
providers: [
{
provide: 'USERS_SERVICE',
useClass: UsersService,
},
],
exports: [UsersService],
})
export class UsersModule {}
users.service.ts
import { Injectable } from '#nestjs/common';
import { InjectModel } from '#nestjs/mongoose';
import { Model } from 'mongoose';
import { CreateUserDto } from 'src/users/dto/user.dto';
import { User, UserDocument } from 'src/users/schemas/user.schema';
import { IUserService } from './user';
#Injectable()
export class UsersService implements IUserService {
constructor(#InjectModel(User.name) private userModel: Model<UserDocument>) {}
// async code for database modification
}
}
Any help would be greatly appreciated! Many thanks!
The token of UsersService provider is the string 'UsersService' (or UsersService.name) not 'USERS_SERVICE'
So just use the short-hand syntax providers: [UsersService] or the right token in provide:.

Categories