ConfigService of nest cannot pull .env variable - nestjs

I wanted to implement the ConfigService of Nestjs v8.1.1
I've place the .env file in the project's root (not src folder) and the file has this content:
HOST=http://localhost
PORT=8088
The app.Module.ts is enriched with the import:
#Module({
imports: [
ConfigModule.forRoot({
isGlobal: true,
cache: true,
envFilePath: '.env',
}),
...]
I've tried without the options and with these listed options.
When it is trying to get the value of the variable, it results in
var address = this.configService.get('HOST', 'http://localhost')
^
TypeError: Cannot read properties of undefined (reading 'get')
FYI the code is run in an extended class, which should not make a difference.
export default class KsqldbSignalsClient extends ClientProxy {
constructor(private configService: ConfigService) {
super()
}
async connect(): Promise<any> {
var address = this.configService.get('HOST', 'http://localhost')
...
Any hint (even confirmation that it works for you) is appreciated.

Decorate the KsqldbSignalsClient class with #Injectable().

Step 1:
Install the 2 packages below
https://www.npmjs.com/package/config
https://www.npmjs.com/package/dotenv
Step 2:
#Module({
imports: [
ConfigModule.forRoot({
host: process.env.HOST,
port: process.env.PORT,
envFilePath: '.env',
}),
...]
Step 3:
Then inside you KsqldbSignalsClient class or anywhere
simply get the value like,
var address = process.env.HOST;

Related

NestJS can't resolve dependency

I'm trying to setup a graphql nestjs clean architecture, I have my resolver call the service, service calls repository and repository calls orm methods. Am I missing a step?
But I get this error:
[Nest] 59764 - 03/10/2022, 16:36:13 ERROR [ExceptionHandler] Nest can't resolve dependencies of the AthleteRepository (?). Please make sure that the argument AthleteEntityRepository at index [0] is available in the GraphQLModule context.
Potential solutions:
- If AthleteEntityRepository is a provider, is it part of the current GraphQLModule?
- If AthleteEntityRepository is exported from a separate #Module, is that module imported within GraphQLModule?
#Module({
imports: [ /* the Module containing AthleteEntityRepository */ ]
})
Error: Nest can't resolve dependencies of the AthleteRepository (?). Please make sure that the argument AthleteEntityRepository at index [0] is available in the GraphQLModule context.
This is my module:
#Module({
imports: [
InfraestructureModule,
NestGraphqlModule.forRoot<MercuriusDriverConfig>({
driver: MercuriusDriver,
graphiql: true,
autoSchemaFile: join(
process.cwd(),
'src/infraestructure/graphql/schema.gql',
),
sortSchema: true,
}),
],
controllers: [AuthResolver, UserResolver],
providers: [
FirebaseService,
AthleteEntity,
AthleteRepository,
AthleteService,
],
})
export class GraphQLModule {}
Adding repository by comment request, it's mostly just wrappers around the typerom Repository.
import { Controller } from '#nestjs/common';
import { InjectRepository } from '#nestjs/typeorm';
import { Repository } from 'typeorm';
import { AthleteEntity } from '../entity/athlete.entity';
#Controller('')
export class AthleteRepository {
constructor(
#InjectRepository(AthleteEntity)
private athleteRepository: Repository<AthleteEntity>,
) {}
async getAthleteByUserId(id: string): Promise<AthleteEntity> {
return this.athleteRepository.findOne({ where: { id } });
}
async getAthletes(): Promise<AthleteEntity[]> {
return this.athleteRepository.find();
}
}
As you use #InjectRepository(AtheleteEntity) you need to have TypeOrmModule.forFeature([AtheleteEntity]) used in the imports of the GraphQlModule.
Side note: Is that supposed to be #Controller() or #Injectable()? It doesn't look like a standard HTTP or RPC controller to me
change AthleteRepository to an #Injectable instead of #Controller.

Unclear error message "Nest can't resolve dependencies of the XXXController (?) <...>" in NestJS

The part after (?) of error message is unclear:
Error: Nest can't resolve dependencies of the MemberController (?).
Please make sure that the argument Object at index [0] is available in
the MemberModule context.
Potential solutions:
If Object is a provider, is it part of the current MemberModule?
If Object is exported from a separate #Module, is that module imported within MemberModule? #Module({
imports: [ /* the Module containing Object */ ] })
Here the incomprehensible moments are:
Object is a broad concept; I can't understand on what it refers
Object at index [0] - at index of what?
MemberModule context - again, the context is a broad concept. Is context the property of some object?
If Object is a provider, is it part of the current MemberModule? - what means the difference between "part of" and "not part of"?
Main module
#NestJS_Module({
imports: [
MemberModule,
TypeOrmModule.forRoot({
type: "postgres",
host: "localhost",
port: 5432,
username: "*******",
password: "*******",
database: "*******",
autoLoadEntities: true,
synchronize: __IS_DEVELOPMENT_BUILDING_MODE__
})
],
controllers: [],
providers: []
})
export default class NestJS_Application {}
Member module
import { Module as NestJS_Module } from "#nestjs/common";
import { TypeOrmModule } from "#nestjs/typeorm";
import MemberModel from "../Data/FromDataBase/Models/Member.model";
import MemberController from "../Controllers/Member.controller";
import MemberTypeORM_Gateway from "../Data/FromDataBase/Gateways/MemberTypeORM_Gateway";
#NestJS_Module({
imports: [ TypeOrmModule.forFeature([ MemberModel ]) ],
controllers: [ MemberController ],
providers: [ MemberTypeORM_Gateway ]
})
export default class MemberModule {}
Member controller
#Controller()
export default class MemberController {
private readonly memberService: MemberGateway;
public constructor(applicationService: MemberGateway) {
this.memberService = applicationService;
}
// ...
}
Because I tried tried the solution for Nest can't resolve dependencies of the PhotoService (?), here must the other solution.

How to register RedisModule in Nest.js?

I've followed the instruction from nestjs-redis documentation to register RedisModule but it gives me the following error message. I am new to Nest.js and have no idea how to fix this error.
If you know the better way to use Redis with nestjs, please suggest me.
Nest can't resolve dependencies of the RedisCoreModule
(Symbol(REDIS_MODULE_OPTIONS), ?). Please make sure that the argument
ModuleRef at index [1] is available in the RedisCoreModule context.
Potential solutions:
If ModuleRef is a provider, is it part of the current RedisCoreModule?
If ModuleRef is exported from a separate #Module, is that module imported within RedisCoreModule? #Module({
imports: [ /* the Module containing ModuleRef */ ] })
my app.module
#Module({
imports: [
RedisModule.register({
host: `${host}`,
port: 6379,
}),
],
})
export class AppModule {}

I'm getting following "Nest can't resolve dependencies of the WorkspaceController..." error in nest.js

I get this error
Nest can't resolve dependencies of the WorkspaceController (?). Please make sure that the argument API_SERVICE at index [0] is available in the WorkspaceModule context.
I have this code
app.module.ts
#Module({
imports: [
ClientsModule.register([
{
name: 'API_SERVICE',
transport: Transport.REDIS,
options: {
url: 'redis://localhost:6379'
}
}
]),
WorkspaceModule
],
controllers: [AppController],
providers: [AppService]
})
workspace.module.ts
#Module({
imports: [],
controllers: [WorkspaceController]
})
export class WorkspaceModule {}
workspace.controller.ts
#Controller()
export class WorkspaceController{
constructor(#Inject('API_SERVICE') private client: ClientProxy) {}
#Get("default-languages")
getDefaultLanguages():Observable<string[]> {
return this.client.send<any>({cmd:'getDefaultLanguages'},{});
}
}
You register the ClientsModule inside of AppModule which means that controlelrs and providers in AppModule's scope (i.e. in its own providers and controllers arrays) have access to that provider (#Inject('API_SERVICE')), but once you leave to another module's scope (like WorkspaceModule), that provider is no longer available. If you need that microservice client in several different modules, I'd suggest making a wrapper module for it, that imports and exports the ClientsModule, otherwise, you just need to move the ClientsMOdule.register from AppModule to WorkspaceModule
Example Wrapper
#Module({
imports: [ClientsModule.register(clientsModuleOptions)],
exports: [ClientsModule],
})
export class WrapperClientsModule {}
It's called module re-exporting

custom config module validation with joi

So I followed the guide on how to create a configuration for my Nest app
https://docs.nestjs.com/techniques/configuration
and due to the fact I have many configuration parts I wanted to split the parts into multiple configuration services. So my app.module.ts imports a custom config module
#Module({
imports: [CustomConfigModule]
})
export class AppModule {}
This custom config module (config.module.ts) bundles all the config services and loads the Nest config module
#Module({
imports: [ConfigModule.forRoot()],
providers: [ServerConfigService],
exports: [ServerConfigService],
})
export class CustomConfigModule {}
Lastly I have a simple config service server.config.service.ts which returns the port the application is running on
#Injectable()
export class ServerConfigService {
constructor(private readonly configService: ConfigService) {}
public get port(): number {
return this.configService.get<number>('SERVER_PORT');
}
}
I would like to validate those services on application startup. The docs explain how to setup a validationschema for the configuration module
https://docs.nestjs.com/techniques/configuration#schema-validation
How can I use that for my service validation when using a custom config module?
Do I have to call joi in each service constructor and validate the properties there?
Thanks in advance
I believe in your ConfigModule.forRoot() you can set the validation schema and tell Nest to run the validations on start up instead of having to add it to each custom config service. The docs show something like:
#Module({
imports: [
ConfigModule.forRoot({
validationSchema: Joi.object({
NODE_ENV: Joi.string()
.valid('development', 'production', 'test', 'provision')
.default('development'),
PORT: Joi.number().default(3000),
}),
validationOptions: {
allowUnknown: false,
abortEarly: true,
},
}),
],
})
export class AppModule {}
Which would run validations on NODE_ENV and PORT. You could of course extend it out to more validations overall. And then you could just have one ConfigModule that has smaller config services that split each segment up so all validations are run on startup and only what you need is available in each module's context.

Resources