Reputation: 3832
I would like to create a REST API with NestJs and TypeORM. In my app.module.ts I load the TypeORM module
@Module({
imports: [
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'postgres',
database: 'api',
entities: [`${__dirname}/**/*.entity.{ts,js}`],
synchronize: true,
}),
],
})
export class AppModule {}
and it's working fine for now. I would like to load the configuration from an external .env file so from the docs
https://docs.nestjs.com/techniques/database#async-configuration
and from here
NestJS Using ConfigService with TypeOrmModule
I created a .env file in the root project directory with the following content
DATABASE_TYPE = postgres
DATABASE_HOST = localhost
DATABASE_PORT = 5432
DATABASE_USERNAME = postgres
DATABASE_PASSWORD = postgres
DATABASE_NAME = api
DATABASE_SYNCHRONIZE = true
Next I update my code to
@Module({
imports: [
ConfigModule.forRoot(),
TypeOrmModule.forRootAsync({
imports: [ConfigModule],
useFactory: async (configService: ConfigService) => ({
type: configService.get<any>('DATABASE_TYPE'),
host: configService.get<string>('DATABASE_HOST'),
port: configService.get<number>('DATABASE_PORT'),
username: configService.get<string>('DATABASE_USERNAME'),
password: configService.get<string>('DATABASE_PASSWORD'),
database: configService.get<string>('DATABASE_NAME'),
entities: [`${__dirname}/**/*.entity.{ts,js}`],
synchronize: configService.get<boolean>('DATABASE_SYNCHRONIZE'),
}),
inject: [ConfigService],
}),
],
})
export class AppModule {}
Unfortunately I get this error on startup
[Nest] 28257 - 01/06/2020, 7:19:20 AM [ExceptionHandler] Nest can't resolve dependencies of the TypeOrmModuleOptions (?). Please make sure that the argument ConfigService at index [0] is available in the TypeOrmCoreModule context.
Potential solutions:
- If ConfigService is a provider, is it part of the current TypeOrmCoreModule?
- If ConfigService is exported from a separate @Module, is that module imported within TypeOrmCoreModule?
@Module({
imports: [ /* the Module containing ConfigService */ ]
})
+1ms
When I log the configuration in my main.ts within the bootstrap function I get a correct configuration from the .env file.
How can I fix the error?
Upvotes: 5
Views: 8281
Reputation: 2682
In case you are using Nestjs-query for graphql, which is this library
Check the library version, I used 5.0.0-alpha-1, this problem came out. The quick solution is just revert back to version-3.0.0, this problem is solved.
Upvotes: 0
Reputation: 820
code translation of @ Jay McDoniel explanation
typeorm.config.ts
import { ConfigModule, ConfigService } from '@nestjs/config';
import { TypeOrmModuleAsyncOptions, TypeOrmModuleOptions } from '@nestjs/typeorm';
import { LoggerOptions } from 'typeorm';
export default class TypeOrmConfig {
static getOrmConfig(configService: ConfigService): TypeOrmModuleOptions {
return {
type: 'postgres',
host: configService.get('DB_HOST') || 'localhost',
port: configService.get('DB_PORT') || 5432,
username: configService.get('DB_USERNAME'),
password: configService.get('DB_PASSWORD'),
database: configService.get('DB_NAME'),
entities: [__dirname + '/../**/*.entity{.ts,.js}'],
synchronize:configService.get<boolean>('TYPEORM_SYNCHRONIZE') || false,
logging: configService.get<LoggerOptions>('TYPEORM_LOGGING') || false
};
}
}
export const typeOrmConfigAsync: TypeOrmModuleAsyncOptions = {
imports: [ConfigModule],
useFactory: async (configService: ConfigService): Promise<TypeOrmModuleOptions> => TypeOrmConfig.getOrmConfig(configService),
inject: [ConfigService]
};
app.module.ts
import { LoginModule } from './login/login.module';
import * as redisStore from 'cache-manager-redis-store';
import { ServiceModule } from './service/service.module';
import { UserModule } from './user/user.module';
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { RedisCacheModule } from './redis-cache/redis-cache.module';
import { typeOrmConfigAsync } from './config/typeorm.config';
import { ConfigModule } from '@nestjs/config';
@Module({
imports: [
ConfigModule.forRoot({ isGlobal: true }),
TypeOrmModule.forRootAsync(typeOrmConfigAsync),
UserModule,
ServiceModule,
LoginModule,
RedisCacheModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
Reference video Reference code
Upvotes: 5
Reputation: 70570
One of two things needs to happen:
1) You need to make your ConfigModule
global by passing the isGlobal: true
option to ConfigModule.forRoot()
. If you do this, then you can remove the import in the TypeormModule.forRootAsync()
(it's then a global module and can have it's providers used anywhere)
2) Make another module (MyConfigModule
or something) that imports
the ConfigModule
with its configuration and exports
the CofnigModule
. Then you can change ConfigModule.forRoot()
to MyConfigModule
in the AppModule
and you can change imports: [ConfigModule]
to imports: [MyConfigModule]
in the TypeormModule.forRootAsync()
configuration.
Upvotes: 9