7

I have created a DatabaseModule using the nestjs typeorm

import { createConnection } from 'typeorm';
import { ConfigService } from '@nestjs/config';


export const databaseConnection = [
    {
        provide: 'DATABASE_CONNECTION',
        useFactory: async (configService: ConfigService) => await createConnection({
            type: configService.get('DBTYPE'),
            host: configService.get('DBHOST'),
            port: configService.get('DBPORT'),
            username: configService.get('DBUSERNAME'),
            password: configService.get('DBPASSWORD'),
            database: configService.get('DBNAME'),
            synchronize: true,
            entities: [
                __dirname + '/../**/*.entity.ts'
            ]
        })
    }
];

While starting the rest service I am getting the following error

Cannot read property 'get' of undefined - {"stack":["TypeError: Cannot read property 'get' of undefined

    at InstanceWrapper.useFactory [as metatype] (../database/database.provider.js:9:33)
    at Injector.instantiateClass (../node_modules/@nestjs/core/injector/injector.js:293:55)
    at callback (../node_modules/@nestjs/core/injector/injector.js:77:41)
    at process._tickCallback (internal/process/next_tick.js:68:7)
    at Function.Module.runMain (internal/modules/cjs/loader.js:834:11)
    at startup (internal/bootstrap/node.js:283:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:623:3)"]}

I have imported the ConfigModule inside DatabaseModule.

Can someone help me out with this?

EDIT

My database config

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

// Configuration factory class for database configuration.
const DatabaseConfig = registerAs('DBConfig', () => ({
    DBTYPE: process.env.DATABASE_TYPE,
    DBHOST: process.env.DATABASE_HOST || 'localhost',
    DBPORT: process.env.DATABASE_PORT || 5432,
    DBUSERNAME: process.env.DATABASE_USERNAME,
    DBPASSWORD: process.env.DATABASE_PASSWORD,
    DBNAME: process.env.DATABASE_NAME
}));

In app.module.ts imports

ConfigModule.forRoot({
        isGlobal: true,
        expandVariables: true,
        load: [AppConfig, DatabaseConfig]
}),
Tony Roczz
  • 2,366
  • 6
  • 32
  • 59

1 Answers1

10

If the ConfigService comes from a global module, you need to add inject into the async configuration, like so:

Since you are using a config.namespace you have invoke it like DBConfig.DBTYPE.

export const databaseConnection = [
    {
        provide: 'DATABASE_CONNECTION',
        inject: [ConfigService],
        useFactory: async (configService: ConfigService) => await createConnection({
            type: configService.get('DBConfig.DBTYPE'),
            host: configService.get('DBConfig.DBHOST'),
            port: configService.get('DBConfig.DBPORT'),
            username: configService.get('DBConfig.DBUSERNAME'),
            password: configService.get('DBConfig.DBPASSWORD'),
            database: configService.get('DBConfig.DBNAME'),
            synchronize: true,
            entities: [
                __dirname + '/../**/*.entity.ts'
            ]
        })
    }
];

If the ConfigService does not come from a global module, you need to add both inject: [ConfigService] and imports: [ConfigModule].

Tony Roczz
  • 2,366
  • 6
  • 32
  • 59
Jay McDoniel
  • 57,339
  • 7
  • 135
  • 147
  • The config service does come from the global module. After adding `inject` the `configService.get('DBTYPE')` returns `undefined` – Tony Roczz Oct 04 '20 at 04:07
  • Well, how is the `ConfigModule` registered? Do you have `DBTYPE` in a `.env` file? You can see the `ConfigService` is working as expected – Jay McDoniel Oct 04 '20 at 04:56
  • I have updated my question. I have invoked the `AppConfig` inside main.ts and it works – Tony Roczz Oct 04 '20 at 07:48
  • 1
    You're using a config namesapce. You need to do `configService.get(namespace.value)`. In this case `configService.get('DBConfig.DBTYPE')` – Jay McDoniel Oct 04 '20 at 15:40