Aryan
Aryan

Reputation: 13

How to access environment variable from JSON file in Angular 4?

I have one file "appsettings.json". It has configuration for some other purpose. I want to put variables from "environment.ts" and "environment.prod.ts" to this file and access inside environment files.

If I'm trying to import/require "appsettings.json" and use values it works in development mode but not in "--prod" with aot enabled. --prod --aot=false works fine

Error being thrown: ERROR in Error encountered resolving symbol values statically. Reference to a local (non-exported) symbol 'json'. Consider exporting the symbol (position 3:5 in the original .ts file), resolving symbol CONFIG

 "ExtraConf" : {
    "CDNPATH": "https://share-dev-cdn.test.net/",
    "ICONPATH":"skin/icons/",
    "APPLTITLE":"Title"
  },
  "Environments" : {
    "production": false,
    "appInsights": {
        "appkey":"0908776554"
    }
  },
  "EnvironmentsProd" : {
    "production": true,
     "appInsights": {
         "appkey":"55678900"
    }
  }


environment.ts
declare var require: any;

var json:any = require("../../appsettings.json");

export const environment = json.Environments;

Upvotes: 1

Views: 9979

Answers (2)

AlokeT
AlokeT

Reputation: 1196

You can try out this approach:

1: ConfigLoaderService:

@Injectable({
  providedIn: 'root'
})
export class ConfigLoaderService {

  private config: Config;

  constructor(private http: HttpClient) {
    this.config = new Config();
  }

  public getConfigData(): Config {
    return this.config;
  }

  load(): Promise<any> {
    console.log(`getSettings:: before http.get call`);
    const promise = this.http.get('../assets/myconfig.json', HttpOptions)
      .toPromise()
      .then((settings: Config) => {
        this.config = settings;
        return settings;
      });

    return promise;
  }
}

This ConfigLoaderService will load the settings from json on app startup.

2: ConfigModel:

export class Config {
    [name: string]: any;
}

This is a generic class will load anything from json as key-value pair.

3: AppMdoule:

... Your imports ...
export function configProviderFactory(provider: ConfigLoaderService) {
  return () => provider.load();
}
@NgModule({
.... Your all imports , declaration...
providers: [
{ provide: APP_INITIALIZER, useFactory: configProviderFactory, deps: [ConfigLoaderService], multi: true },


.... Your other providers ....
  ],

So what happened here, You declare to angular that when app initialize it will first call the configLoaderService and load the config json file from assets and set in the config class which is accessible thorough out the application. Now you can access the models through this.

export class MyComponent implements OnInit {

  private config: Config;

  constructor(
    configLoader: ConfigLoaderService,

  ) {

    this.config = configLoader.getConfigData();

  }

  ngOnInit() {
    console.log(this.config['MY_URL']);
    console.log(this.config.MY_URL);
  }

Note: This will work in NG5+ but for Ng4 you need to change httpClient import.

Upvotes: 4

Satish Deokar
Satish Deokar

Reputation: 216

Instead of creating the .json file create the appsettings.js file and export the json configuration from file.

    //appsettings.js file
    configValue = {
    "ExtraConf": {
        "CDNPATH": "https://share-dev-cdn.test.net/",
        "ICONPATH": "skin/icons/",
        "APPLTITLE": "Title"
    },
    "Environments": {
        "production": false,
        "appInsights": {
            "appkey": "0908776554"
        }
    },
    "EnvironmentsProd": {
        "production": true,
        "appInsights": {
            "appkey": "55678900"
        }
    }
}
exports.configValue = configValue;

then import your appsettings.js file under the environment.ts file and asses configuration like this.

import * as config from './appsettings.js';

export const environment = configValue.Environments;

And For Production Like this. //environment.prod.ts import * as config from './appsettings.js';

export const environment = configValue.EnvironmentsProd;

Note: appsettings.js and environment.ts and environment.prod.ts is in the same folder otherwise you have to change the import path.

Upvotes: 2

Related Questions