Getting environment variable from JSON file within Angular 4 - a step-by-step guide

I have a file named "appsettings.json" which contains configurations for a specific purpose. I want to include variables from both "environment.ts" and "environment.prod.ts" in this file and access them within the environment files.

When I attempt to import/require "appsettings.json" and use its values, it works in development mode but not in "--prod" mode with aot enabled. However, it works fine with "--prod --aot=false" enabled.

An error is 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;

Answer №1

One possible approach to consider is outlined below:

1: Initialize 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;
  }
}

The ConfigLoaderService is responsible for loading settings from a JSON file during app startup.

2: ConfigModel:

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

This is a versatile class designed to interpret JSON data as key-value pairs.

3: AppModule:

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


.... Other providers ....
  ],

By declaring this in the AppModule, Angular is informed to execute the configLoaderService on app initialization, fetching and populating the config class for use throughout the application. Thus, access to the models is facilitated.

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: Compatibility is assured for NG5+, with an adjustment required for Ng4 due to the httpClient import.

Answer №2

Instead of generating a .json file, consider creating an appsettings.js file to export the JSON configuration.

    //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;

Next, import the appsettings.js file into the environment.ts file to access the configuration.

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

export const environment = configValue.Environments;

For Production, follow this approach. //environment.prod.ts import * as config from './appsettings.js';

export const environment = configValue.EnvironmentsProd;

Note: Ensure that appsettings.js, environment.ts, and environment.prod.ts are located in the same folder. Otherwise, adjust the import paths accordingly.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Ways to detect button click in a separate component

I am working with an Angular app that consists of two components: a navbar component and a display component. The navbar component has a search button that, when clicked, searches for the entered name and displays the details in the display component. I ne ...

Guide to sending a request to a third-party API using Node.js and Express.js with the 'Authorization: Basic' header

Attempting to utilize the UDEMY API, each request necessitates the inclusion of Authorization: Basic + keys header. The API documentation specifies: curl --user {YOUR_CLIENT_ID}:{YOUR_CLIENT_SECRET} https://www.udemy.com/api-2.0/courses/ curl -H "Au ...

Exploring the Power of Modules in NestJS

Having trouble with this error - anyone know why? [Nest] 556 - 2020-06-10 18:52:55 [ExceptionHandler] Nest can't resolve dependencies of the JwtService (?). Check that JWT_MODULE_OPTIONS at index [0] is available in the JwtModule context. Possib ...

Issues with Angular2 causing function to not run as expected

After clicking a button to trigger createPlaylist(), the function fails to execute asd(). I attempted combining everything into one function, but still encountered the same issue. The console.log(resp) statement never logs anything. What could be causing ...

SCORM-compliant Angular web application bundle

As I work on my angular web project, I am looking to create a SCORM package in order to easily integrate it into any LMS system. I have a few questions regarding the packaging process and compatibility: What is the best way to package my project for SCORM ...

Using Symbol.iterator in Typescript: A step-by-step guide

I have decided to upgrade my old React JavaScript app to React Typescript. While trying to reuse some code that worked perfectly fine in the old app, I encountered errors in TS - this is also my first time using TS. The data type I am exporting is as foll ...

Encountering a hiccup while trying to install Svelte, Skeleton, and Tail

Recently entering the world of Svelte and TypeScript, I have encountered some unexpected errors after installation. Despite following the same steps as before, I am puzzled by what is causing these issues. This is the process I followed: npm create svelte ...

The function is missing a closing return statement and the return type does not specify 'undefined'

It seems like the function lacks an ending return statement and the return type does not include 'undefined'. In a recent refactoring of the async await function called getMarkets, I noticed that I had mistakenly set the return type as Promise: ...

What is the best way to convert an HTML table into an array of objects?

In my Angular Protractor end-to-end (e2e) tests, I need to perform assertions on an HTML fragment similar to the following: <table> <thead> <tr> <th>Name</th> <th>Age</th> ...

It appears that Spring Boot is not making a custom header visible to my frontend application

Currently, I am working with a Spring Boot backend and an Angular frontend, where my goal is to enable the download functionality for a pdf file. To achieve this, I have included the following handler in my REST-controller: @GetMapping("/{id}" ...

What is the best way to insert an item into a tree structure when determining the appropriate level for insertion is necessary beforehand?

Currently, I am dealing with a tree-like object structure: interface Node { id: number; name: string; children?: Node[]; } NODE_DATA: Node[] = [ { id: 1, name: 'A' }, { id: 2, name: 'B', children: [ ...

Having trouble showing table data in Angular

My goal is to showcase data from a table created using Spring-Boot Below is my model.ts: export class Quiz1 { QuestionId?: any; Question?: string; OptionsA?: string; OptionsB?: string; OptionsC?: string; OptionsD?: string;} He ...

Unable to utilize the Object.values method with an object in TypeScript

I am attempting to create an array of values from all the keys within an object by using the Object.values(obj) function, but I encountered the following error message: No overload matches this call. Overload 1 of 2, '(o: { [s: string]: string; } | ...

The type 'MouseEvent<HTMLButtonElement, MouseEvent>' cannot be matched with the type 'boolean'

Just starting out with TS and running into a problem that TS is pointing out to me. Error: Type '(x: boolean) => void' is not compatible with type '(e: MouseEvent<HTMLButtonElement, MouseEvent>) => void'. Parameters ' ...

Moving the marker does not update the address

When the dragend event is triggered, the Getaddress function will be called in the following code: Getaddress(LastLat, LastLng , marker,source){ this.http.get('https://maps.googleapis.com/maps/api/geocode/json?latlng='+LastLat+ &apos ...

TypeScript generic types allow you to create reusable components that

function genericIdentity<T>(arg: T): T { return arg; } let myGenericIdentity: <U>(arg: U) => U = genericIdentity; I see that the 'genericIdentity' function is accepting an argument of a generic type. However, I am unsure about ...

When working in VScode, there may be difficulty in locating project-specific imports for `tsx` files. However, the TypeScript compiler is able to locate

When converting a jsx component to tsx, my VScode editor highlights project-specific imports as errors. The following code is from components\molecules\WizardSteps.jsx JSX https://i.stack.imgur.com/tKZ35.png TSX The following code is from comp ...

Issues encountered when utilizing a computed property in Typescript to organize an array

Attempting to implement Vue in a typescript single page application, I encountered a challenge where arrays needed to be displayed on screen in sorted lists. Despite the seemingly simple nature of the problem, none of the examples I came across seemed to w ...

Updates to TypeScript 2.3.1 creating disruptions in SystemJS plunk

Check out this official Angular + TypeScript plunk using SystemJS 0.19.31, now updated to TypeScript 2.3.0. However, changing the SystemJS configuration in the same plunk to TypeScript 2.3.1 or 2.3.2 'typescript': 'npm:<a href="/cdn-cgi ...

Exploring the Nested JSON Data Loop with *ngFor in Angular 5/4

Recently I started working with Angular, and I've created a service to iterate over nested JSON data for my list. export const CATEGORIES: Category[] = [ { id: 1, categoryName:'Accessories', subcatName: [ {subcategory: & ...