Nestjs can't resolve dependencies of XModel - node.js

I have been working on this app for like 3 months which is near completion. But since yesterday I have been unable to solve this problem. I want to use activityTypeService in activityLogService and I have been getting this wired error. I have already exported activityTypeservice in its module. see below
below is ActivityTypeModule, I export ActivityTypeService so it can available in ActivityLogService
#Module({
imports: [MongooseModule.forFeature([{ name: 'ActivityType', schema: ActivityTypeSchema },])],
providers: [ActivityTypeService,],
controllers: [ActivityTypeController],
exports: [ActivityTypeService,]
})
export class ActivityTypeModule { }
The code below is activityLog module and ActivityTypeModule is imported
#Module({
imports: [MongooseModule.forFeature([{ name: 'ActivityLog', schema: ActivityLogSchema }]), ActivityTypeModule],
providers: [ActivityLogService, ActivityTypeModule],
controllers: [ActivityLogController],
exports: [MongooseModule,]
})
export class ActivityLogModule { }
so I use it the activityLogService as shown below
#Injectable()
export class ActivityLogService {
constructor(#InjectModel('ActivityLog') private activitylogModel: Model<ActivityLog>,
private activityTypeService: ActivityTypeService
) { }
async activitylog(activityuser: string, activitytype: string, activitydetails: string, activitydate: Date) {
const activitiesLog = {
activityuser: activityuser,
activitytype: activitytype,
activitydetails: activitydetails,
activitydate: activitydate
}
const activity = new this.activitylogModel(activitiesLog);
console.log(activity);
await activity.save()
}
}
But I am still getting this wired error which I dont understand
Nest can't resolve dependencies of the ActivityTypeService (?). Please make sure that the argument ActivityTypeModel at index [0] is available in the ActivityTypeService context.
Potential solutions:
- If ActivityTypeModel is a provider, is it part of the current ActivityTypeService?
- If ActivityTypeModel is exported from a separate #Module, is that module imported within ActivityTypeService?
#Module({
imports: [ /* the Module containing ActivityTypeModel */ ]
})

From your error, somewhere you have ActivityTypeService in an imports array somewhere, which shouldn't be happening. Along with that, I can see you have ActivityTypeModule in a providers array, which is also not supported, though Typescript doesn't have a good way to show errors about that, so you aren't seeing any errors.
In general, as Nest error like that is in the form of
Nest can't resolve dependencies of the <Provider> (?). Please make sure that the argument <injected_valued> at index [<index>] is available in the <module> context.
<Provider> and <module> should never be the same value, and if they are, it's a good indication that you have a provider in an imports array.

Related

NestJS dynamic module registration

I have a question regarding dynamic modules importing.
Let's say I have #Injectable service which depends on the parameter that came from the configuration:
#Injectable()
export class StatsService {
constructor(#Inject(SERVICE_NAME) private serviceName: string) {}
...
}
Let's say I expose this service through the Dynamic module:
#Module({})
export class CoreServicesModule {
static register(coreConfig: CoreServicesConfig): DynamicModule {
const { serviceName } = coreConfig;
return {
module: CoreServicesModule,
providers: [
{
provide: SERVICE_NAME,
useValue: serviceName
},
StatsService
],
exports: [
StatsService
]
};
}
}
Let's say my application is pretty big, and I have a lot of different modules.
But I need StatsService in every one of them.
So for example to be able to use StatsService in one of the modules i need to do something like:
#Module({
imports: [CoreServicesModule.register({ serviceName: 'test', ... })]
})
export class SomeModule { ... }
And I need to do it for each module...
Do we have a way to do it only once in NestJS?
Or how we can re-use the already registered module?
#Global decorator also not help me here cause I still need to import the module in each place...
#Global() decorator will help you if you are interested in using StatService in all other modules without the need to import that module!
BUT from your code it seems that each module that import CoreServicesModule would also make a small adjustment to it by dynamically specifying the providers it has (such as ValidationPipe).
in that case you should NOT make it #Global() since global modules should be registered only once

Nest can't resolve dependencies of AuthService

I am following the documentation present here
https://docs.nestjs.com/techniques/authentication#jwt-functionality
To have faster support I have created a git repository with the problem
https://github.com/Sano123456/nestjs-jwt
node -v -> v10.15.2
npm -v -> 6.14.6
nest -v -> 7.4.1
First Problem:
in AuthModule if I do as described in documentation and just import UserModule, it return me error of circular dependency between UserModule and AuthModule
#Module({
imports:[
UsersModule,
PassportModule
],
providers: [AuthService],
controllers: [AuthController],
exports:[AuthService, LocalStrategy]
})
export class AuthModule {}
error:
[ExceptionHandler] Nest cannot create the AuthModule instance.
The module at index [0] of the AuthModule "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 [0] is of type "undefined". Check your import statements and the type of the module.
Scope [AppModule -> UsersModule] +6ms
Possibile solution in imports array of AuthModule instead of UserModule put forwardRef(() => UsersModule),
this actually remove the error but not sure if this is the right way
Second problem:
it says that can't find LocalStrategy class even if it's present and declared in AuthModule
[ExceptionHandler] Nest cannot export a provider/module that is not a part of the currently processed module (AuthModule). Please verify whether the exported LocalStrategy is available in this particular context.Is LocalStrategy part of the relevant providers/imports within AuthModule?
Possibile solution right now I don't have any solution, I just remove it to understand what is the problem
Third problem :
after removing LocalStrategy,
[ExceptionHandler] Nest can't resolve dependencies of the AuthService (?). Please make sure that the argument dependency at index [0] is available in the AuthModule context.
Potential solutions:
- If dependency is a provider, is it part of the current AuthModule?
- If dependency is exported from a separate #Module, is that module imported within AuthModule?
#Module({
imports: [ /* the Module containing dependency */ ]
})
+1ms
Error: Nest can't resolve dependencies of the AuthService (?). Please make sure that the argument dependency at index [0] is available in the AuthModule context.
anyone solved this issues?
You have a circular dependancy because your UsersModule and your AuthModule import each other. Therefore you have 2 options to repair this issue.
The first is to make a forward reference which will allow both modules to be built simultaneously and once built, pass in the reference required. This is done like so:
#Module({
imports: [
forwardRef(() => UsersModule),
],
...
})
export class AuthModule {}
// And the same for your UsersModule
#Module({
imports: [
forwardRef(() => AuthModule),
],
})
export class UsersModule {}
The second option is to remove the dependancies from one another. This is not always possible and guessing by the names of your modules I would argue this isn't possible. You don't want to have the auth module accessing the user module's database and services etc outside the users module. But I'll give you some advice on module inheritance.
Module in nestjs are built asynchronously. Meaning they have to be structured like a cascading tree with one module importing all the others. Something linear will look like this
AppModule <= CatModule <= PawsModule
Another example would be dual importing
<= CatModule
AppModule <= PawsModule
<= DogModule
In the above example, the paws module is created once and imported in both cat and dog module. Meaning paws module will be built first before cat and dog module.
So to explain your error you need to think from a linear code perspective and how the module import tree will share modules that import each other. Because they import each other, nest can't decide which to create first so will need a reference to pass back, hence the function. I've always imagined the container's forward ref function as saying "Hey, hold this for a sec" (it's a piece of paper that says "UsersModule") then turns around, does some wavey of the arms with his back turned, then turns around and replaces the piece of paper with the UsersModule!
Your second issue is you never created a provider for LocalStrategy. It doesn't exist in the AuthModule so cannot be imported into AuthService nor exported from AuthModule!
** SOLUTION of problem "can't resolve dependencies" **
For the first and second problem the final solution is to use #Inject(forwardRef(() => AuthService)) in UserService
here is example
#Injectable()
export class UserService {
constructor(
#InjectRepository(User) private readonly UserRepository: Repository<User>,
private readonly config: ConfigService,
#Inject(forwardRef(() => AuthService)) //<---
private readonly authService: AuthService,
) {
}
Same thing also in AuthService
#Injectable()
export class AuthService {
private client: any;
constructor(
#Inject(forwardRef(() => UserService))//<--- here
private readonly userService: UserService,
#InjectConfig() private readonly config,
) {
}
In AuthModule and UserModule you need to still use forwardRef
I never used this solution before and i never needed it, but this solved my issue
Regarding LocalStrategy, put it in providers array of the module
For me, it wasn't enough to just use the forwardRef on both services as in Sano's answer; I also had to forwardRef on both circular dependent modules too.
In both services:
https://docs.nestjs.com/fundamentals/circular-dependency#forward-reference
import { forwardRef, Inject } from '#nestjs/common';
...
#Inject(forwardRef(() => UserService))`
In both modules:
https://docs.nestjs.com/fundamentals/circular-dependency#module-forward-reference
import { forwardRef } from '#nestjs/common';
...
imports: [
forwardRef(() => UsersModule),
],

Nestjs cannot resolve dependency index[0] when decorator is being used

I am new to NestJs and i have a question for you that i could not resolve it.
UsersService has two dependencies
-TypeOrm UsersRepository Injection
-WalletsService Injection
Typeorm injection is done by decorator as you see down below.
//UsersService
#Injectable()
export class UsersService implements IUserService {
constructor(
#InjectRepository(Users)
private usersRepository: Repository<Users>,
private readonly walletsService: WalletsService,
) { }
Whenever i changed first injection it cannot be resolved.
Probably i am missing something. There are all photos down below with description
//UsersModule
#Module({
controllers: [UsersController],
exports: [UsersService],
imports: [WalletsModule, TypeOrmModule.forFeature([Users])],
providers: [UsersService],
})
export class UsersModule { }
//WalletsModule
#Module({
controllers: [WalletsController],
exports: [WalletsService],
imports: [TypeOrmModule.forFeature([Wallets])],
providers: [WalletsService]
})
export class WalletsModule { }
[When Users Repository is first injection]
Nest can't resolve dependencies of the UsersService (?, WalletsService). Please make sure that the argument UsersRepository at index [0] is available in the UsersService context.
Potential solutions:
- If UsersRepository is a provider, is it part of the current UsersService?
- If UsersRepository is exported from a separate #Module, is that module imported within UsersService?
#Module({
imports: [ /* the Module containing UsersRepository */ ]
})
[When Wallets Service is first injection ]
Nest can't resolve dependencies of the UsersService (?, UsersRepository). Please make sure that the argument WalletsService at index [0] is available in the UsersService context.
Potential solutions:
- If WalletsService is a provider, is it part of the current UsersService?
- If WalletsService is exported from a separate #Module, is that module imported within UsersService?
#Module({
imports: [ /* the Module containing WalletsService */ ]
})
Thank you in advance. I hope it is descriptive enough. Have good day!
For posterity of the answer from the comments:
There was a service in an imports array which leads to problems with Nest trying to resolve things. In general, these errors can start to be debugged knowing that Nest's error is in the form of
Nest can't resolve dependencies of the UsersService (<dependencies_with_unknown_as_?>. Please make sure that the argument <unknown_dependency> at index [] is available in the <related_module> context.

Using imported interceptor on controller not working in nestjs

I like to organise my project along feature lines with different modules for cross cutting concerns eg: configuration, authentication, etc. However when importing an Interceptor into a feature module for use with a Controller Nest doesn't seem to reuse the existing instance.
controllers.module.ts
#Module({
imports: [
// ConfigService is exported from this module.
ConfigModule
],
providers: [
// For debugging purposes I used a factory so I could place a breakpoint and see
// when the Interceptor is being created.
{
provide: MyInterceptor,
useFactory: (config: ConfigService) => new MyInterceptor(config),
inject: [
ConfigService
]
}
],
exports: [
MyInterceptor
]
})
export class ControllersModule {
}
customer.module.ts
#Module({
imports: [
ControllersModule
],
controllers: [
CustomerController
],
providers: [
CustomerService
]
})
export class CustomerModule {
}
customer.controller.ts
#Controller("/customers")
#UseInterceptors(MyInterceptor)
export class CustomerController {
constructor(private readonly customerService: CustomerService) {
}
#Get()
customers() {
return this.customerService.findAll();
}
}
When the application starts up, I can see the MyInterceptor provider factory being called, with an instance of ConfigService. However then I see the following error on the console
error: [ExceptionHandler] Nest can't resolve dependencies of the MyInterceptor (?). Please make sure that the argument ConfigService at index [0] is available in the CustomerModule context.
Potential solutions:
- If ConfigService is a provider, is it part of the current CustomerModule?
- If ConfigService is exported from a separate #Module, is that module imported within CustomerModule?
#Module({
imports: [ /* the Module containing ConfigService */ ]
})
Now maybe there's something about how Nest instantiates/uses Interceptors that I'm not understanding but I thought that given that MyInteceptor had been created, and the ControllersModule imported by CustomerModule that the bean would have been available and applied to CustomerController.
Is there something I'm missing here?
Interceptors (along with other request lifecycle classes) are kinda like pseudoproviders in that that are #Injectable() but they aren't added to a providers array for binding. You can bind then via the providers array, (APP_INTERCEPTOR) but that will cause it to be bound globally.
Because interceptors can't be added to a providers array the way you are trying, you need to instead add the ConfigModule to whatever module uses the interceptor.
and as a side-note, you shouldn't use #Res with interceptors in nestjs
why
look, when you are using an interceptor, you are handling (with using .handle()) the stream of response (observable) not a whole package of it, but using express #Res actually is somehow getting around the whole flow of response streaming.
this is also explicitly mentioned in nestjs official documents:
We already know that handle() returns an Observable. The stream
contains the value returned from the route handler, and thus we can
easily mutate it using RxJS's map() operator.
WARNING
The response mapping feature doesn't work with the
library-specific response strategy (using the #Res() object directly
is forbidden).

NestJS cannot verify argument is available in current context/Mongoose Inject Model

I followed the MongoDB tutorial on the nestjs website but am unable to replicate it in my own project, I have cloned the nextjs repo and verified that the mongo sample supplied there runs fine.
This is what I currently have (minified):
app.module.ts
#Module({
imports: [
MongooseModule.forRoot('mongodb://localhost/nest')
],
modules: [
CampaignModule
]
})
export class AppModule implements NestModule {}
}
campaign.module.ts
#Module(
{
modules: [SharedModule],
controllers: [CampaignController],
components: [CampaignService],
imports: [MongooseModule.forFeature([{name: 'Campaign', schema: campaignSchema}])]
})
export class CampaignModule {}
campaign.service.ts
#Component()
export class CampaignService {
constructor(#InjectModel(campaignSchema) private readonly campaignModel: Model<CampaignInterface>) {}
}
this builds fine as expected but when I run it i get this error:
Nest can't resolve dependencies of the CampaignService (?). Please verify whether [0] argument is available in the current context.
So because in my app.module.ts I have the campaign module in the modules section (how i have had it so far working fine prior to mongodb) I moved it into the imports sections with the MongooseModule now it will build and run fine, but the routes inside the controller for campaign.controller.ts do not register at all, they just return 404's. This is weird because the example in the nestjs repo have the CatsModule inside the imports with the MongooseModule and it works.
Any tips here would be appreciated. this is my schema and interface for the campaign object as well:
export interface CampaignInterface extends Document, Campaign {
}
export const campaignSchema: any = new mongoose.Schema({
campaignId: String
});
EDIT 1
I moved all my modules into the import section of my app.module.ts file as before I tried it with CampaignModule in imports and all the others in modules: []. It now fails right away when served with the same error and no routes are registered.
Ok I figured out what is going on,
It seems that if you have both a modules: [] and imports: [] inside your #Module decorator the modules: [] takes over and completely ignores the imports: []. So in my campaign.module.ts file I moved the SharedModule from modules: [] into imports: [] after the MongooseModules.forFeature import. It now works and write to mongo!

Resources