#"undefined" when retrieving values from the config

12 messages · Page 1 of 1 (latest)

charred gyro
#

When retrieving values from the config, it returns undefined, but when I use the same method to retrieve values in another file or get a different value, it works normally.

cedar geode
#

Can you show the code that's returning undefined vs the working parts?

charred gyro
#

App Module:

@Module({
  imports: [
    ConfigModule.forRoot({
      ignoreEnvFile: !!process.env.CI,
      envFilePath: join(__dirname, '..', '.env'),
      validationSchema: envSchema,
    }),
    TypeOrmModule.forRootAsync({
      useClass: TypeOrmConfigService,
    }),
    // Throttler - Protection
    ThrottlerModule.forRoot([
      {
        ttl: Number(process.env.THROTTLER_TTL),
        limit: Number(process.env.THROTTLER_LIMIT),
      },
    ]),
    PassportModule.registerAsync({
      imports: [ConfigModule],
      inject: [ConfigService],
      useFactory: async (configService: ConfigService) => ({
        defaultStrategy: configService.get('jwt.defaultStrategy'),
      }),
    }),
    ScheduleModule.forRoot(),
    AuditModule,
    LoggerModule,
    AuthModule,
    UserModule,
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {
  configure(consumer: MiddlewareConsumer): void {
    consumer.apply(SetIpMiddleware).forRoutes('api');
    consumer.apply(LoggerMiddleware).forRoutes('api');
  }
}

App Config file:

import { registerAs } from '@nestjs/config';

export default registerAs('app', () => ({
  appName: process.env.APP_NAME,
  environment: process.env.NODE_ENV,
  baseUrl: process.env.BASE_URL,
  port: parseInt(process.env.PORT, 10),
  logLevel: process.env.LOG_LEVEL.split(','),
}));
#

LoggerService file:

import { ConfigService } from '@nestjs/config';
import { ConsoleLogger, Injectable } from '@nestjs/common';
import { LogLevel } from './enums';

@Injectable()
export class LoggerService extends ConsoleLogger {
  private logLevel: boolean;
  private errorLevel: boolean;
  private warnLevel: boolean;
  private debugLevel: boolean;
  private verboseLevel: boolean;

  constructor(private readonly configService: ConfigService) {
    super();
    const logLevelStrings: string[] =
      this.configService.get<string[]>('app.logLevel');
    console.log(logLevelStrings, this.configService.get('app.logLevel'), this.configService.get<string>('app.appName'), configService.get('jwt.defaultStrategy'));
    const logLevel: LogLevel[] = logLevelStrings.map(
      (level: string) => LogLevel[level.trim() as keyof typeof LogLevel],
    );
    logLevel.forEach((logLevel: LogLevel) => {
      this[`${logLevel}Level`] = true;
    });
  }
...
#

Error:

cedar geode
#

What module contains LoggerService? LoggerModule?

charred gyro
#

Main.ts

import { LoggerService } from './logger';
import { FastifyInstance } from 'fastify';

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );

  // Custom LoggerService for logging
  app.useLogger(app.get(LoggerService));

Logger/index.ts

export { LoggerModule } from './logger.module';
export { LoggerService } from './logger.service';

Logger/logger.module.ts

import { Module } from '@nestjs/common';
import { ConfigModule } from '@nestjs/config';
import { LoggerService } from './logger.service';

@Module({
  imports: [ConfigModule],
  providers: [LoggerService],
  exports: [LoggerService],
})
export class LoggerModule {}
cedar geode
#

I think this comes from using ConfigModule in the imports again without the forRoot/register. Personally, I've never liked how @nestjs/config works, it's one of those wonky kind of modules. I'd probably suggest just making the call in the AppModule as global: true or isGlobal: true (whichever it is) and then not worry about it

charred gyro
#

Thanks, it works. I didn't notice that another module has ConfigModule.forFeature(mailConfig).

#

But I'm wondering if I can unify this and apply something similar in main.ts, or if it has to stay as it is?

async function bootstrap() {
  const app = await NestFactory.create<NestFastifyApplication>(
    AppModule,
    new FastifyAdapter(),
  );

  const configService: ConfigService = app.get(ConfigService);

  const port = configService.get<string>('PORT', '');

  await app.register(
    fastifyRedis as Parameters<NestFastifyApplication['register']>[0],
    {
      host: configService.get<string>('REDIS_HOST', ''),
      port: configService.get<string>('REDIS_PORT', ''),
      password: configService.get<string>('REDIS_PASSWORD', ''),
    },
  );

  await app.register(
    secureSession as Parameters<NestFastifyApplication['register']>[0],
    {
      sessionName: configService.get<string>('SESSION_NAME', ''),
      cookieName: configService.get<string>('SESSION_COOKIE', ''),
      expiry: configService.get<string>('SESSION_EXPIRATION_TIME', ''),
      cookie: {
        path: '/',
        httpOnly: true,
        secure: configService.get<string>('NODE_ENV') === 'production',
      },
      secret: configService.get<string>('SESSION_SECRET', ''),
      salt: configService.get<string>('SESSION_SALT', ''),
      store: {
        type: 'redis',
        options: {
          client: fastifyInstance.redis,
        },
      },
    },
  );
cedar geode
#

What do you mena?