Getting error while running specs
- If MailerService is a provider, is it part of the current RootTestModule?
- If MailerService is exported from a separate #Module, is that module imported within RootTestModule?
#Module({
imports: [ /* the Module containing MailerService */ ]
})
app.module.ts
#Module({
imports: [
UserService,
MailerModule.forRoot({
transport: process.env.SMTP_TRANSPORT,
defaults: {
from: process.env.SMTP_FROM,
},
preview: true,
template: {
dir: __dirname + '/templates',
adapter: new PugAdapter(),
options: {
strict: true,
},
},
})
]
in User Service
import { MailerService } from '#nestjs-modules/mailer';
export class UserService {
constructor(private readonly mailerService: MailerService ) {}
}
While running specs for Userservice i am getting error MailerService is a provider, is it part of the current RootTestModule?
Related
I need to use the ConfigService to get the environment variables, but when I use "forRootAsync" of the TypeOrmModule nestjs is unable to resolve the DataService dependency
This is my module
#Module({
imports: [
ConfigModule.forRoot({ validate: validateConfig(AssetEnvironmentVariables), isGlobal: true }),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
inject: [ConfigService],
useFactory: (configService: ConfigService): TypeOrmModuleOptions => ({
type: "postgres",
host: configService.get("PG_HOST"),
port: configService.get("PG_PORT"),
database: configService.get("PG_DB_NAME"),
username: configService.get("PG_USER"),
password: configService.get("PG_PASSWORD"),
entities: [AssetEntity],
migrations: ["./migrations/*"],
}),
});
],
providers: [
{ provide: AssetRepository, useClass: AssetPostgresRepository },
],
})
export class AssetModule {}
This is the implementation to AssetRepository
#Injectable()
export class AssetPostgresRepository extends AssetRepository {
private typeOrmRepository: Repository<AssetEntity>;
constructor(dataSource: DataSource) {
super();
this.typeOrmRepository = dataSource.getRepository(AssetEntity);
}
async save(asset: Asset): Promise<void> {
try {
await this.typeOrmRepository.save(asset.toPrimitives());
} catch (e) {
throw new SavingRepositoryException(e);
}
}
}
This is the error that it throw me
ERROR [ExceptionHandler] Nest can't resolve dependencies of the AssetPostgresRepository (?). Please make sure that the argument DataSource at index [0] is available in the AssetModule context.
Potential solutions:
- Is AssetModule a valid NestJS module?
- If DataSource is a provider, is it part of the current AssetModule?
- If DataSource is exported from a separate #Module, is that module imported within AssetModule?
#Module({
imports: [ /* the Module containing DataSource */ ]
})
I created my Dynamic configModule to extract environment variables from a different path. It extracts from an yml file. Everything works properly if a add in some module. Here is my ConfigModule:
import { DynamicModule } from '#nestjs/common';
import { ConfigModule } from '#nestjs/config';
import { EnvConfigService } from './env.config.service';
export class EnvConfigModule {
/**
* Create an static function to call directly from the class without instantiation
* #param options: Our config module attributes or properties
* #returns DynamicModule
*/
static register(options): DynamicModule {
return {
module: ConfigModule,
providers: [
{
provide: 'CONFIG_OPTIONS',
useValue: options,
},
EnvConfigService,
],
exports: [EnvConfigService],
};
}
}
Now when I want to add that configuration in the new custom JwtModule, CustomJwtModule:
...
import { EnvConfigModule } from 'src/utils/environment/env.config.module';
import { EnvConfigService } from 'src/utils/environment/env.config.service';
#Module({
imports: [
JwtModule.registerAsync({
imports: [EnvConfigModule],
inject: [EnvConfigService],
useFactory: (configService: EnvConfigService) => {
const base64_pubKey = configService.get(ACCESS_PUBLIC_KEY_NAME);
return {
publicKey: Buffer.from(base64_pubKey, KEY_ENCODING),
signOptions: {
algorithm: ENCRYPTION_ALGORITHM,
},
};
},
}),
],
providers: [
{
provide: JWT_ACCESS_SERVICE,
useExisting: JwtService,
},
],
exports: [JWT_ACCESS_SERVICE],
})
export class JWTAccessModule {}
And here is my error:
Error: Nest can't resolve dependencies of the JWT_MODULE_OPTIONS (?). Please make sure that the argument EnvConfigService at index [0] is available in the JwtModule context.
I guess, I do get that error because it does not inject properly in JWT module my service.
My app.module.ts is implemented in that way
...
import { EnvConfigModule } from './utils/environment/env.config.module';
#Module({
imports: [
IamModule,
EnvConfigModule.register({
folder: 'config/environment/',
}),
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Ok, it seems I was importing wrongly. It was missing some part of the configuration. Here is the working example of CustomJwtModule:
...
import { EnvConfigModule } from 'src/utils/environment/env.config.module';
import { EnvConfigService } from 'src/utils/environment/env.config.service';
#Module({
imports: [
JwtModule.registerAsync({
imports: [EnvConfigModule.register({
folder: 'config/environment/',
}),
],
inject: [EnvConfigService],
...
I try to decouple the controller module of a NestJs module from a domain module (as per clean architecture principles), so that dependency flows only to Domain.
I do not understand how to make it work, injection of the repo interface's implementation does not happen (error when nest starts).
Here is the module structure :
AppModule -> CommunityControllerModule -> DomainModule
(provides repoImpl (has service requiring an unknown
by token) concrete repo interface impl)
The CommunityControllerModule :
import { DomainModule } from 'libs/domain/src';
import { Module } from '#nestjs/common';
import { CommunityController } from './community.controller';
import { CommunityRepositoryImpl } from './community.repository';
#Module({
imports: [DomainModule, CommunityRepositoryImpl],
controllers: [CommunityController],
exports: [CommunityRepositoryImpl],
providers: [
{
provide: 'CommunityRepository',
useClass: CommunityRepositoryImpl,
},
],
})
export class CommunityControllerModule {}
The DomainModule :
import { Module } from '#nestjs/common';
import { CommunityService } from './community.service';
#Module({
providers: [CommunityService],
exports: [CommunityService],
})
export class DomainModule {}
The CommunityService where injection fails :
import { HttpException, HttpStatus, Inject, Injectable } from '#nestjs/common';
import { CommunityRepository } from './community.repo';
#Injectable()
export class CommunityService {
constructor(
#Inject('CommunityRepository') private repo: CommunityRepository,
) {}
}
The outputted error :
> nest start
webpack 5.28.0 compiled successfully in 8218 ms
[Nest] 7204 - 2021-05-05 20:52:05 [NestFactory] Starting Nest application...
[Nest] 7204 - 2021-05-05 20:52:05 [InstanceLoader] CommunityRepositoryImpl dependencies initialized +49ms
[Nest] 7204 - 2021-05-05 20:52:05 [ExceptionHandler] Nest can't resolve dependencies of the CommunityService (?). Please make sure that the argument CommunityRepository at index [0] is available in the DomainModule context.
Potential solutions:
- If CommunityRepository is a provider, is it part of the current DomainModule?
- If CommunityRepository is exported from a separate #Module, is that module imported within DomainModule?
#Module({
imports: [ /* the Module containing CommunityRepository */ ]
})
What I missed was to set the DomainModule as a dynamic module.
The Domain module becomes :
import { DynamicModule, Module } from '#nestjs/common';
import { CommunityService } from './community.service';
#Module({})
export class DomainModule {
static register(repoImpl): DynamicModule {
return {
module: DomainModule,
imports: [repoImpl],
providers: [
CommunityService,
{
provide: 'CommunityRepository',
useClass: repoImpl,
},
],
exports: [CommunityService],
};
}
}
...and the CommunityControllerModule imports it with the repo implementation :
import { DomainModule } from 'libs/domain/src';
import { Module } from '#nestjs/common';
import { CommunityController } from './community.controller';
import { CommunityRepositoryImpl } from './community.repository';
#Module({
imports: [
DomainModule.register(CommunityRepositoryImpl),
CommunityRepositoryImpl,
],
controllers: [CommunityController],
exports: [CommunityRepositoryImpl],
providers: [
{
provide: 'CommunityRepository',
useClass: CommunityRepositoryImpl,
},
],
})
export class CommunityControllerModule {}
How can we inject connection dependencies of the subscriber with yml files .
my files are :
ormconfig.yml
default:
type: 'postgres'
host: 'localhost'
port: 5432
username: 'postgres'
password: 'root'
database: 'hiring_db'
entities: ["dist/**/*.entity{.ts,.js}"]
synchronize: true
logging: ["query","error"]
logger: "file"
extra: { timezone: "+5:30" }
migrations: ["src/migrations/*.ts"]
cli: {
migrationDir: 'src/migrations'
}
subscribers: ["src/**/*.subscriber{.ts,.js}"]
JobPostingModule.ts
import { Module } from '#nestjs/common';
import { JobPostingController } from './job-posting.controller';
import { JobPostingService } from './job-posting.service';
import { AuthModule } from '../auth/auth.module';
import { RecruitmentService } from '../recruitment/recruitment.service';
#Module({
imports: [
AuthModule
],
controllers: [JobPostingController],
providers: [JobPostingService, RecruitmentService]
})
export class JobPostingModule {}
JobSubscriber.ts
import { Injectable } from '#nestjs/common';
import { InjectConnection } from '#nestjs/typeorm';
import { Jobs } from 'src/entities/job-posting.entity';
import { Connection, EntitySubscriberInterface, getConnection, InsertEvent, UpdateEvent } from 'typeorm';
import { JobPostingService } from './job-posting.service';
#Injectable()
export class JobSubscriber implements EntitySubscriberInterface {
constructor(private readonly connection: Connection) {
connection.subscribers.push(this); // <---- THIS
}
listenTo() {
return Jobs;
}
afterInsert(event: InsertEvent<Jobs>) {
console.log('Hi guys!');
};
afterUpdate(event: UpdateEvent<any>) {
console.log('Hi guys!');
}
}
I am getting this error Nest can't resolve dependencies of the JobSubscriber (?). Please make sure that the argument Connection at index [0] is available in the AppModule context.
Potential solutions:
- If Connection is a provider, is it part of the current AppModule?
- If Connection is exported from a separate #Module, is that module imported within AppModule?
#Module({
imports: [ /* the Module containing Connection */ ]
})
do not use subscribers: ["src/**/*.subscriber{.ts,.js}"]
just add connection.subscribers.push(this); logic
and use the subscriber as a module Provider.
You can refer to the official NestJS documentation for this problem.
import { Module } from '#nestjs/common';
import { TypeOrmModule } from '#nestjs/typeorm';
#Module({
imports: [
TypeOrmModule.forRoot(),
],
})
export class AppModule {}
Once you imported the TypeOrmModule you can use Connection as a provider everywhere.
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 !