I am trying to implement a global module in nest.js
I have created a service like below
export interface ConfigData {
DB_NAME: string;
}
@Injectable()
export class ConfigManager {
private static _instance?: ConfigManager;
public static configData:ConfigData | null;
private constructor() {
console.log(ConfigManager)
if (ConfigManager._instance)
ConfigManager._instance = this;
else{
ConfigManager._instance = new ConfigManager()
ConfigManager.configData = <ConfigData|null><unknown>ConfigManager.fetchSecretData()
}
}
private static async fetchSecretData():Promise<ConfigData|null>{
// some data from db
}
// static get instance() {
// return ConfigManager._instance ?? (ConfigManager._instance = new ConfigManager());
// //return ConfigManager._instance ?? (ConfigManager._instance = ConfigManager.fetchSecretData()) //new ConfigManager());
// }
}
configuration.module.ts
@Global()
@Module({
providers: [ConfigManager],
exports: [ConfigManager],
})
export class ConfigurationModule {}
and in app.module.ts added ConfigurationModule
in imports.
Also adding private constructor on service unable it to add in module.ts file.
I am expecting that I should be able to configData
anywhere without importing the ConfigManager. but it's not working...
ConfigManager
is not available without import.
I am trying to implement a global module in nest.js
I have created a service like below
export interface ConfigData {
DB_NAME: string;
}
@Injectable()
export class ConfigManager {
private static _instance?: ConfigManager;
public static configData:ConfigData | null;
private constructor() {
console.log(ConfigManager)
if (ConfigManager._instance)
ConfigManager._instance = this;
else{
ConfigManager._instance = new ConfigManager()
ConfigManager.configData = <ConfigData|null><unknown>ConfigManager.fetchSecretData()
}
}
private static async fetchSecretData():Promise<ConfigData|null>{
// some data from db
}
// static get instance() {
// return ConfigManager._instance ?? (ConfigManager._instance = new ConfigManager());
// //return ConfigManager._instance ?? (ConfigManager._instance = ConfigManager.fetchSecretData()) //new ConfigManager());
// }
}
configuration.module.ts
@Global()
@Module({
providers: [ConfigManager],
exports: [ConfigManager],
})
export class ConfigurationModule {}
and in app.module.ts added ConfigurationModule
in imports.
Also adding private constructor on service unable it to add in module.ts file.
I am expecting that I should be able to configData
anywhere without importing the ConfigManager. but it's not working...
ConfigManager
is not available without import.
-
1
How are you trying to make use of the
ConfigManager
? – Jackie McDoniel Commented Nov 22, 2021 at 17:07 - I want to access like ConfigManager. property of this class.. but the thing is ConfigManager is not accessible without import – Md Parvez Alam Commented Nov 23, 2021 at 3:57
-
1
Without import like
import { ConfigManager } from './config-manager.provider.ts
? – Jackie McDoniel Commented Nov 23, 2021 at 17:22 - Yes, I like to add this to global and can access simply like ConfigManger.someproperty – Md Parvez Alam Commented Nov 24, 2021 at 3:42
-
Well, to assign to globals, you'd just need to do
globals.ConfigManager = ConfigManager
. That said, I would highly suggest not using globals as they don't provide clarity and can start confusing things in the end – Jackie McDoniel Commented Nov 24, 2021 at 17:22
3 Answers
Reset to default 4You've only marked your module with @Global
decorator, but the NestJS needs to somehow initialize that module and make it globally available.
What this means is that you have to add this module to your core application module and NestJS will do the rest for you, so something like this (or however your root module is named):
@Module({
imports: [ConfigurationModule],
})
export class AppModule {}
From the documentation
The @Global() decorator makes the module global-scoped. Global modules should be registered only once, generally by the root or core module.
Global modules in nest only means you don't have to include that module in the imports: [] of every other module that requires it's providers. The providers in the global module still behaves as as normal providers i.e. you need to inject it where you need it.
So in your case since you have already added @Global() to ConfigManager
and imported ConfigurationModule
in app.module.ts
, you will not need to add ConfigurationModule
in imports for any other modules who want to use ConfigManager
. You would, however, still need to inject the ConfigManager
provider - that's what @Injectable()
means :).
To do the injection, you need a constructor(private configManager: ConfigManager) {}
in the class that needs to use ConfigManager
, and since you need access to the type of the class, you'll need import { ConfigManager } from '../path/to/ConfigManager'
as well.
this is 'per-design' of es6/ts: you cant use the class without importing it.
you are mixing the concepts of di (instantiation/position) with importing (defining which classes are available in the module scope)