1

I have node module created from Angular 5 application and I have Angular 5 application which must use that node module. Is there any way to read Angular 5 application environment variable(environments/environment.ts) from my node module? Maybe Angular 5 exports its environment variables to JavaScript global variables after build and my node module can get it from JavaScript?

I would be grateful for any help

Mher
  • 985
  • 9
  • 23

2 Answers2

3

The node module should not read from the environment file directly. There is no guarantee what file structure the user's environment files are in, or if they even have environment files. So the node_module should be totally agnostic to environements and instead you should pass in a variable when you import the module. This gives the application (and it's environment files) full control over what the node_module uses.

// app.module.ts
import { environment } from './environments/environment';


@NgModule({
    imports: [MyNodeModule.setup(environment.myVar)]
})
export class AppModule {}

This allows the user to either pass in a static value or a dynamic value from their own environment files.


Update

To make the passed in value available to your node_module you can use an InjectionToken

export const MY_TOKEN = new InjectionToken<string>('My passed in token');

In your MyModule you provide this token and assign it the value that was passed in.

@NgModule()
export class MyNodeModule {
    static setup(myToken: string) {
        return {
            ngModule: MyNodeModule,
            providers: [{ provide: MY_TOKEN, useValue: myToken }]
        }
    }
}

Now for the rest of your node_module to use the token, you can inject it.

@Injectable()
export class SomeService {
    constructor(@Inject(MY_TOKEN) private myToken){}
}

Here is a very basic stackblitz demoing this functionality.

LLai
  • 13,128
  • 3
  • 41
  • 45
  • I would not import the variable in the Module but create a config service, like this https://stackoverflow.com/questions/43193049/app-settings-the-angular-4-way/43193574#43193574 – masterfloda Dec 19 '17 at 00:09
  • Thanks @LLai for your answer. It sounds good for me. I never used setup. Can you please provide example how MyModule can get that variable? – Mher Dec 19 '17 at 00:54
  • @MherAghabalyan I've updated my answer. I'm not sure how you need to use the environment variable, but the provided stackblitz demos how you can pass in a value to `MyNodeModule` – LLai Dec 19 '17 at 17:26
2

This is how I solve my issue.

I created abstract class in my node module

import { Injectable } from '@angular/core';

@Injectable()
export abstract class ConfigService {
    constructor() { }
    public abstract getAppConfigProperties(): any;
    public abstract getAppEnvironmentProperties(): any;
}

and another class in my main application which extended this one

import { Injectable } from '@angular/core';
import { ConfigService } from 'my_node_module';
import {environment} from '../../environments/environment';
import {appConfig} from '../app.config';

@Injectable()
export class AppConfigService extends ConfigService {
    public getAppConfigProperties(): any {
      return appConfig;
    }
    public getAppEnvironmentProperties(): any {
      return environment;
    }

}

getAppConfigProperties and getAppEnvironmentProperties methods return all variables that I need in my node module. And at the end I added this row to my main application module.

providers: [
    AppConfigService,
    { provide: ConfigService, useExisting: AppConfigService },
...

now I can use ConfigService functions in my node module to get information I need from main app.

@Injectable()
export class CoreService {
    constructor( private configService: ConfigService ) { }

    public getWhatIneed(): void {
        console.log( this.configService.getAppConfigProperties() );
    }
Mher
  • 985
  • 9
  • 23