Nest can't resolve dependencies of the services - node.js

When I used person Service in the Organisation Service, I got the error like this:
Nest can't resolve dependencies of the PersonService (PersonModel, ?). Please make sure that the argument at index [1] is available in the OrganizationModule context.
Organization.service.ts
#Injectable()
export class OrganizationService {
constructor(
#InjectModel('Organization') private readonly organizationModel: Model<Organization>,
#Inject(forwardRef(() => UsersService))
private readonly usersService: UsersService,
private readonly mailerService: MailerService,
#Inject(forwardRef(() => PersonService))
private readonly personService: PersonService,
) {}
Organization.module.ts
#Module({
imports: [
RateLimiterModule.register({ type: 'Memory', points: 100, duration: 60 * 5, keyPrefix: 'organization' }),
MongooseModule.forFeature([
{ name: 'Organization', schema: OrganizationSchema },
{ name: 'User', schema: UserSchema },
{ name: 'Person', schema: PersonSchema },
]),
PassportModule.register({ defaultStrategy: 'jwt', session: false }),
forwardRef(() => UsersModule),
forwardRef(() => PersonModule),
],
exports: [OrganizationService],
controllers: [OrganizationController],
providers: [OrganizationService, UsersService, PersonService]
})
Person.module.ts
#Module({
imports: [
RateLimiterModule.register({ type: 'Memory', points: 100, duration: 60 * 5 }),
MongooseModule.forFeature([
{ name: 'Person', schema: PersonSchema },
{ name: 'User', schema: UserSchema },
]),
PassportModule.register({ defaultStrategy: 'jwt', session: false }),
forwardRef(() => UsersModule),
],
exports: [PersonService],
controllers: [PersonController],
providers: [PersonService, UsersService]
})
export class PersonModule {
public configure(consumer: MiddlewareConsumer) {
consumer
.apply(LoggerMiddleware)
.forRoutes(PersonController);
consumer
.apply(SiteMiddleware)
.forRoutes(PersonController);
}
}
What is the error in this code?

You shouldn't re-add dependencies to providers arrays. You already define the PersonService provider in the PersonModule, and the PersonModule properly exports that provider, so all that needs to happen is the OrganizationModule needs to have PersonModule in the imports.
By putting PersonService in the OrganizationModule's providers, Nest will try to recreate the provider in the context of the OrganiztionModule, meaning it will need access to getModelToken('Person') and UsersService as other providers in the current context.

Related

can't inject custom repository without #InjectRepository decorator

In NestJS Documentation, it says that when I make custom repository, I don't need to use #InjectRepository() decorator docs
But in my code, I cannot inject my custom repository like that
these are my codes
app.module.ts
#Module({
imports: [
CacheModule.register(),
ConfigModule.forRoot({
isGlobal: true
}),
TypeOrmModule.forRootAsync({
useFactory: () => ({
type: 'postgres',
host: process.env.DB_HOST,
port: +process.env.DB_PORT,
username: process.env.DB_NAME,
password: process.env.DB_PASSWORD,
database: process.env.DB_DATABASE,
entities: [`${__dirname}/**/entities/*.entity{.ts,.js}`],
synchronize: true,
logging: true
})
}),
GraphQLModule.forRoot<ApolloDriverConfig>({
driver: ApolloDriver,
cors: {
origin: 'http://localhost:3000',
credentials: true
},
autoSchemaFile: 'schema.gql'
}),
AuthModule,
UserModule,
]
})
export class AppModule {}
user.repository.ts
#EntityRepository(User)
export class UserRepository extends Repository<User> {}
user.module.ts
#Module({
imports: [TypeOrmModule.forFeature([UserRepository]), CacheModule.register()],
providers: [
UserResolver,
UserService,
],
exports: [UserService, TypeOrmModule]
})
export class UserModule {}
user.service.ts
#Injectable()
export class UserService {
constructor(
private readonly userRepository: UserRepository,
#Inject(CACHE_MANAGER) private cacheManager: Cache
) {}
}
error message
ERROR [ExceptionHandler] Nest can't resolve dependencies of the UserService (?, CACHE_MANAGER). Please make sure that the argument UserRepository at index [0] is available in the UserModule context.
Potential solutions:
- If UserRepository is a provider, is it part of the current UserModule?
- If UserRepository is exported from a separate #Module, is that module imported within
UserModule?
#Module({
imports: [ /* the Module containing UserRepository */ ]
})
I don't want to use #InjectRepository(UserRepositry) decorator.
How can I do that?

findTrees method does not work in Nest JS

I've got a problem using tree entity. I'm using typeORM with nestjs.
My entity is this:
#Entity()
#Tree('closure-table')
export class PermissionEntity {
#PrimaryGeneratedColumn()
id: number;
#Column({ nullable: true, unique: true })
key: string;
#Column({ nullable: true })
displayName?: string;
#TreeChildren()
children: PermissionEntity[];
#TreeParent()
parent: PermissionEntity;
}
In my module I added the entity this way :
#Module({
imports: [
UsersModule,
RolesModule,
TypeOrmModule.forFeature([PermissionEntity]),
],
providers: [
{
provide: 'PERMISSION_SERVICE',
useClass: PermissionsService,
},
{
provide: 'APP_GUARD',
useClass: JwtAuthGuard,
},
],
controllers: [PermissionsController],
})
export class PermissionsModule {}
The codes below is my service file:
export class PermissionsService {
constructor(
#InjectRepository(PermissionEntity)
private readonly permissionRepository: TreeRepository<PermissionEntity>,
#Inject('USER_SERVICE') private readonly userService: UsersService,
#Inject('ROLES_SERVICE') private readonly rolesService: RolesService,
) {}
async create(registerPermissionDto: RegisterPermissionDto) {
this.permissionRepository.create(registerPermissionDto);
return this.permissionRepository.save(registerPermissionDto);
}
async getUserPermissions(userId: number, ownerId: number) {
return this.permissionRepository.findTrees();
}
}
When getUserPermissions() service is called this error occures in console:
[Nest] 10644 - 08/12/2022, 8:15:44 PM ERROR [ExceptionsHandler] this.permissionRepository.findTrees is not a function
I've searched every where and I could not succeed in finding a solution ! Is there a bug with nestJs and typeORM Tree entity ? Or do we have working example ?
use like this:
first inject this
#InjectDataSource()
private readonly dataSource: DataSource,
then:
this.dataSource.getTreeRepository(PermissionEntity).findTrees();

How to do unit testing to #Inject with ClientKafka in NestJS

I need to do some unit test to a kafka implementation in my project with NestJS but I don't know how to do it.
I have a Service thats inject a Client Kafka
export class Service {
private static readonly logger = new Logger(ProducerService.name);
constructor(
#Inject('kafka-registrar') private client: ClientKafka,
private someOtherService: SomeOtherService,
) {}
Module
#Module({
imports: [
ClientsModule.register([
{
name: 'kafka-registrar',
transport: Transport.KAFKA,
options: {
client: {
clientId: 'hero',
brokers: ['localhost:9092'],
},
consumer: {
groupId: '1',
},
},
},
]),
SomeOtherService,
],
providers: [Service],
})
export class Module {}
Unit test
describe('Test Controller', () => {
let clientKafka: ClientKafka;
let someOtherService: SomeOtherService;
let producerService: ProducerService;
beforeEach(async () => {
const moduleRef = await Test.createTestingModule({
providers: [
ProducerService,
{
provide: SchemaRegistryService,
useValue: {
encodeWithId: jest.fn(),
},
},
{
provide: ClientKafka,
useValue: {
emit: jest.fn(),
},
},
],
}).compile()
clientKafka = moduleRef.get(ClientKafka);
schemaRegistryService = moduleRef.get(SchemaRegistryService);
producerService = moduleRef.get(ProducerService);
});
The project give me this error:
Error: Nest can't resolve dependencies of the ProducerService (?, SchemaRegistryService). Please make sure that the argument kafka-registrar at index [0] is available in the RootTestModule context.
Potential solutions:
- If kafka-registrar is a provider, is it part of the current RootTestModule?
- If kafka-registrar is exported from a separate #Module, is that module imported within RootTestModule?
#Module({
imports: [ /* the Module containing kafka-registrar */ ]
})
I don't know how to resolve this in NestJS. For example in Java,I belive that this can be with #Mock ClientKafka clientKafka bit I dont have any other experience with NestJS... Please helpme! :)
In your test file, you can change provide: ClientKafka to this provide: 'kafka-registrar'.
const moduleRef = await Test.createTestingModule({
providers: [
ProducerService,
{
provide: SchemaRegistryService,
useValue: {
encodeWithId: jest.fn(),
},
},
{
provide: 'kafka-registrar',
useValue: {
emit: jest.fn(),
},
},
],
}).compile()

Test InjectModel using Jest and nestjs-typegoose

My controller has a argument is a InjectModel, code:
constructor(
#InjectModel(Poll) private readonly model: ReturnModelType<typeof Poll>,
){
}
and the Poll code is:
import { prop, modelOptions, getModelForClass } from '#typegoose/typegoose';
import { ApiProperty, ApiPropertyOptions } from '#nestjs/swagger';
#modelOptions({
schemaOptions: {
timestamps: true
}
})
export class Poll {
#ApiProperty({
})
#prop({required: true})
title: string
#prop({required: true})
description: string
#prop()
poll: number
#prop({select: false})
userId: string
#prop()
userName: string
}
Jest code:
import { Poll } from '#libs/db/models/poll.model';
const module: TestingModule = await Test.createTestingModule({
imports: [PollsModule],
controllers: [PollsController],
providers: [
{
provide: getModelForClass(Poll),
useValue: getModelForClass(Poll)
},
]
}).compile();
and I get this error:
Nest can't resolve dependencies of the PollsController (?). Please make sure that the argument PollModel at index [0] is available in the PollsModule context.
Potential solutions:
- If PollModel is a provider, is it part of the current PollsModule?
- If PollModel is exported from a separate #Module, is that module imported within PollsModule?
#Module({
imports: [ /* the Module containing PollModel */ ]
})
poll is in a global model as 'DbModel', and DbModel is in the appModel. so the testModel need imports the DbModel, and then fix !

Nestjs global cache: CacheInterceptor problem

After configured cache globally like the docs, the CacheInterceptor throws an error if i use it outside the app.module.
app.module.ts
const cacheConfig = {
store: redisStore,
host: 'localhost',
port: 6379
}
#Module({
imports: [
CacheModule.register(cacheConfig),
CustomerModule,
],
providers: [
{
provide: APP_INTERCEPTOR,
useClass: CacheInterceptor
}
]
})
export class AppModule {}
customer.module.ts
#Module({
imports: [TypeOrmModule.forFeature([CustomerRepository]), TypeOrmModule.forFeature([User])],
controllers: [CustomerController]
})
export class CustomerModule {}
customer.controller.ts
#Controller('customer')
export class CustomerController {
constructor(
#InjectRepository(CustomerRepository) private customerRepository: CustomerRepository,
#InjectRepository(User) private userRepository: Repository<User>
) {}
#Get()
#UseInterceptors(CacheInterceptor)
async get(): Promise<any> {
const user = await this.userRepository.findOne({ where: { id: 1 }, relations: ['customer'] })
console.log(user.customer.name)
const customer = await this.customerRepository.findOne({ where: { id: 1 }, select: ['id', 'name'] })
return { customer: customer.name, email: user.email }
}
}
I would like using the CacheInterceptor along any modules without import the CacheModule each one.
Nest can't resolve dependencies of the APP_INTERCEPTOR (UUID: 6aa42c77-1bac-4098-b217-1b01eb268240) (?, Reflector). Please make sure that the argument at index [0] is available in the CustomerModule context.
If you have { provide: APP_INTERCEPTOR, useClass: CacheInterceptor } you don't need to add in the #UseInterceptors() decorator in your controller. You should have the CahceInterceptor working by default with the rest of the set up

Resources