So, I have my RootModule, a ProductModule and a StoreModule.
My RootModule:
#Module({
imports: [
ProductModule,
StoreModule,
],
controllers: [],
providers: [],
})
export class RootModule {}
My ProductModule:
#Module({
providers: [ProductService],
exports: [],
})
export class ProductModule {}
My StoreModule:
#Module({
imports: []
providers: [StoreService, StoreWaitingService],
})
export class ProductModule {}
Since my RootModule imports ProductModule, shouldn't I be able to use ProductService on StoreService and StoreWaitingService?
What if I imported ProductModule on StoreModule imports?
You can use Product Module and Service in StoreService
Product Module
#Module({
providers: [ProductService],
exports: [ProductService],
})
export class ProductModule {}
Store Module
#Module({
imports: [ProductModule],
})
export class StoreModule{}
Store service
import ProductService from '<Product Service Path>';
...
constructor(private readonly productService: ProductService){}
...
//in Function
this.productService.someFunction();
But if you don't want to import the product module in Store Module, you can make the Product Module a global Module -
https://docs.nestjs.com/modules#global-modules
Related
I have two modules whose services are dependent on one another.
// organization.module.ts
//...imports
#Module({
imports: [
forwardRef(() => EmployeeModule),
TypeOrmModule.forFeature([
OrganizationRepository,
Employee
])
],
controllers: [OrganizationController],
providers: [
OrganizationService
]
})
export class OrganizationModule {}
Organization Service*
#Injectable()
export class OrganizationService {
constructor(
#InjectRepository(OrganizationRepository)
private orgRepository: OrganizationRepository,
#InjectRepository(Employee)
private employeeRepsoitory: Repository<Employee>,
private readonly employeeService: EmployeeService,
){}
//...
}
Then i have my employee module and service
employee.module.ts
#Module({
imports: [
forwardRef(() => OrganizationModule),
//...
]
controllers: [EmployeeController],
providers: [EmployeeService, JwtStrategy],
exports: [EmployeeService],
})
export class EmployeeModule {}
and then i have my employee service
employee.service.ts
#Injectable()
export class EmployeeService {
constructor(
private readonly organizationService: OrganizationService
) {}
Now i am getting this DI error and i dont know what is going wrong here. I have tried
#Inject(forwardRef(() => Service)) but didnt seem to work.
My app.module.ts looks like
//...
#Module({
imports: [
OrganizationModule,
],
controllers: [AppController],
providers: [
AppService,
],
})
export class AppModule {}
What am i doing wrong?
You are missing an exports in OrganizationModule.
Add to OrganizationModule:
exports: [OrganizationService]
I am fairly new to nestJs. I am trying to implement an authentication process according to nestjs documentation, but I don't want to route the login in the app.controller I want to put it in the users.controller, so the route will be /users/login. However, since the AuthModule already uses the UsersService in my code and the login logic with JWT is in the AuthService. Importing it back to the UsersService create a circular dependency. I need help.
To avoid circular dependancy, in your UsersModule, you need to import your AuthModule with ForwardRef like that :
import ...
#Module( {
imports: [
forwardRef( () => AuthModule ),
],
controllers: [],
providers: [],
exports: []
} )
export class UsersModule {
}
If you haven't already done so, you'll need to export the AuthService in AuthModule :
import ...
#Module( {
imports: [],
controllers: [],
providers: [],
exports: [
AuthService
]
} )
export class AuthModule {
}
Okay so I'm using TYPEORM_ prefixed environment variables to register TypeOrmModule into my app. Then I'm loading entities using .forFeature() like so:
#Module({
imports: [TypeOrmModule.forFeature([Foo])],
controllers: [FooController],
providers: [FooService],
exports: [TypeOrmModule],
})
export class FooModule {}
No matter whether I use forRoot() or forRoot({ autoLoadEntities: true }) in AppModule, I get RepositoryNotFoundError: No repository for "Foo" was found. Looks like this entity is not registered in current "default" connection? error while working with the dev server. Any idea what's going on? My service looks like:
#Injectable()
export class FooService {
constructor(#InjectRepository(Foo) private readonly fooRepository: Repository<Foo>) {}
}
I tried the followings as single and/or combined, still didn't solve the issue.
Put a name in #Entity() decorator.
#Entity('foo')
export class Foo {}
Try forRootAsync().
#Module({
imports: [
TypeOrmModule.forRootAsync({
useFactory: async () =>
Object.assign(await getConnectionOptions(), { autoLoadEntities: true }),
}),
FooModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Pass 'default' to forFeature().
#Module({
imports: [TypeOrmModule.forFeature([Foo], 'default')],
controllers: [FooController],
providers: [FooService],
exports: [TypeOrmModule],
})
export class FooModule {}
Try using entities key in forRoot().
#Module({
imports: [
TypeOrmModule.forRoot({ entities: [Foo] }),
FooModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
try to define connectionName inside getConnectionOptions
example:
#Module({
imports: [
TypeOrmModule.forRootAsync({
useFactory: async () =>
Object.assign(await getConnectionOptions('default'), { autoLoadEntities: true }),
}),
FooModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
I am using #nestjs/jwt in my NestJS project.
I have two modules, AuthModule and AppModule.
The AuthModule uses the #nestjs/jwt
The AppModule invoke auth service from AuthModule.
AuthService:
import { Injectable } from '#nestjs/common';
import { JwtService } from '#nestjs/jwt';
import { ForbiddenException } from '#nestjs/common';
#Injectable()
export class AuthService {
constructor(private readonly jwt: JwtService) {}
async validate(token: string) {
return this.jwt.verify(token);
}
...
}
AuthModule:
import { Module } from '#nestjs/common'
import { TokenService } from './auth.service'
import { ConfigModule, ConfigService } from '#nestjs/config'
import { JwtModule } from '#nestjs/jwt'
#Module({
imports: [
JwtModule.register({
secret: "mysecret",
signOptions: { expiresIn: "60s" },
}),
],
// I provide AuthService & JwtService
providers: [AuthService, JwtService],
// I export AuthService and JwtService
exports: [AuthService, JwtService],
})
export class AuthModule {}
AppModule:
#Module({
imports: [
AuthModule,
...
],
controllers: [AppController],
// I provide AuthService & JwtService also in AppModule
providers: [AppService, JwtService],
})
export class AppModule {}
(The AppController invokes AuthService instance to validate token.)
I constantly get error:
Nest can't resolve dependencies of the JwtService (?). Please make sure that the argument JWT_MODULE_OPTIONS at index [0]
Why is that? Where do I miss?
You don't need to add JwtService to the providers. Nest will look through the current module's providers, then the imported module's exports, and then the global module's exports to find providers that are not immediately in the level it's resolving the providers in. This means that for AuthService it'll look up to the JwtModule's exports and find the JwtService already created, and use that instance. Then in the AppModule you don't need to mention the AuthService or JwtService, just import the AuthModule that exports the AuthService and JwtModule (doing some module re-exporting) and you should be good to go
EDIT: Added module code:
AuthModule
import { Module } from '#nestjs/common'
import { TokenService } from './auth.service'
import { ConfigModule, ConfigService } from '#nestjs/config'
import { JwtModule } from '#nestjs/jwt'
#Module({
imports: [
JwtModule.register({
secret: "mysecret",
signOptions: { expiresIn: "60s" },
}),
],
providers: [AuthService],
exports: [AuthService, JwtModule],
})
export class AuthModule {}
AppModule
#Module({
imports: [
AuthModule,
...
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
I am trying to inject a ContentsService into a SlackModule so that I can use some of the Content functions in my Slack Controller.
This is app.module
#Module({
imports: [
ContentsModule,
ZapierModule,
SlackModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Here is my Contents Module:
import { Module } from '#nestjs/common';
import { MongooseModule } from '#nestjs/mongoose';
import { ContentsController, ZapierController, SlackInteractiveController } from './contents.controller';
import { ContentsService } from './contents.service';
import { ContentSchema } from './content.model';
#Module({
imports: [
MongooseModule.forFeature([{ name: 'Content', schema: ContentSchema }]),
],
controllers: [ContentsController, ZapierController, SlackInteractiveController],
providers: [ContentsService],
exports: [ContentsService],
})
export class ContentsModule {}
This is my Slack Module:
import { Module } from '#nestjs/common';
import { SlackService } from './slack.service';
import { SlackController } from './slack.controller';
import { ContentsService } from '../contents/contents.service';
#Module({
providers: [SlackService],
controllers: [SlackController],
imports: [ContentsService],
})
export class SlackModule {}
And my Slack Controller
import { ContentsService } from '../contents/contents.service'
#Controller('slackevents')
export class SlackController {
constructor(private contentsService: ContentsService) {}
But when I run this code, I get this error:
[Nest] 75628 - 05/22/2020, 7:08 AM [ExceptionHandler] Nest can't resolve dependencies of the ContentsService (?). Please make sure that the argument at index [0] is available in the ContentsService context. +44ms\
What is it that I am doing wrong?
Services and other providers do not belong in the imports array. Only module classes should go in there. You should have imports: [ContentsModule] in your SlackModule and you'll have access to the ContentsService