Skip to main content

Async Configuration

When you need to pass module options asynchronously instead of statically, use the .forRootAsync() method. As with most dynamic modules, Nest provides several techniques to deal with async configuration.

One technique is to use a factory function:

src/app.module.ts
import { NecordModule } from 'necord';
import { Module } from '@nestjs/common';
import { IntentsBitField } from 'discord.js';

@Module({
imports: [
NecordModule.forRootAsync({
useFactory: () => ({
token: 'DISCORD_BOT_TOKEN',
intents: [
IntentsBitField.Flags.Guilds,
IntentsBitField.Flags.GuildMessages,
IntentsBitField.Flags.DirectMessages
]
})
})
]
})
export class AppModule {}

Like other factory providers, our factory function can be async and can inject dependencies through inject.

src/app.module.ts
import { ConfigModule, ConfigService } from '@nestjs/config';
import { Module } from '@nestjs/common';
import { IntentsBitField } from 'discord.js';
import { NecordModule, NecordModuleOptions } from 'necord';

@Module({
imports: [
NecordModule.forRootAsync({
imports: [ConfigModule.forRoot()],
useFactory: (configService: ConfigService): NecordModuleOptions => ({
token: configService.getOrThrow<string>('DISCORD_BOT_TOKEN'),
intents: [
IntentsBitField.Flags.Guilds,
IntentsBitField.Flags.GuildMessages,
IntentsBitField.Flags.DirectMessages
]
}),
inject: [ConfigService]
})
]
})
export class AppModule {}

Alternatively, you can configure the NecordModule using a class instead of a factory, as shown below:

src/app.module.ts
import { NecordModule } from 'necord';
import { Module } from '@nestjs/common';
import { NecordConfigService } from './discord-config.service';

@Module({
imports: [
NecordModule.forRootAsync({
useClass: NecordConfigService
})
]
})
export class AppModule {}

The construction above instantiates NecordConfigService inside NecordModule, using it to create the required options object. The class must expose a createNecordOptions() method returning NecordModuleOptions; NecordModule calls this method on the supplied class.

src/discord-config.service.ts
import { Injectable } from '@nestjs/common';
import { NecordModuleOptions } from 'necord';
import { IntentsBitField } from 'discord.js';

@Injectable()
export class NecordConfigService {
public createNecordOptions(): NecordModuleOptions {
return {
token: 'DISCORD_BOT_TOKEN',
intents: [
IntentsBitField.Flags.Guilds,
IntentsBitField.Flags.GuildMessages,
IntentsBitField.Flags.DirectMessages
]
};
}
}

If you want to reuse an existing options provider instead of creating a private copy inside the NecordModule, use the useExisting syntax.