Personally, I am not a fan of using the http.get method to read the config.json file for handling configuration information. I believe there are more elegant ways to simply include and read the json file in your code, especially when working with Angular2 and Typescript. Why not leverage classes, interfaces, and implement it in a more sophisticated manner?
When I first started learning Angular2, I came across an example of how they managed config files in the Dependency Injection guide. I found this approach effective for managing config information such as API endpoints and default values in the apps I have worked on.
As per the documentation:
Non-class dependencies
[...]
Applications often define configuration objects with lots of small facts (like the title of the application or the address of a web API endpoint) but these configuration objects aren't always instances of a class.
One solution to choosing a provider token for non-class dependencies is to define and use an OpaqueToken.
To handle this, you would need to create a config object with URLs and other necessary details, followed by an OpaqueToken
usage for injecting this configuration object.
All my configurations are included in the app-config.ts
file.
// Although the ApplicationConfig interface plays no role in dependency injection,
// it supports typing of the configuration object within the class.
export interface ApplicationConfig {
appName: string;
apiEndpoint: string;
}
// Configuration values for our app
export const MY_CONFIG: ApplicationConfig = {
appName: 'My new App',
apiEndpoint: 'http://www...'
};
// Create a config token to avoid naming conflicts
export const MY_CONFIG_TOKEN = new OpaqueToken('config');
Initially, understanding what an OpaqueToken
is might be tricky, but essentially, it's just a string used to prevent naming conflicts during object injection. You can find a detailed post about this concept here.
To utilize this, you simply need to include it in the desired page like so:
import { NavController } from 'ionic-angular/index';
import { Component, OpaqueToken, Injectable, Inject } from "@angular/core";
// Import the config-related things
import { MY_CONFIG_TOKEN, MY_CONFIG, ApplicationConfig } from 'app-config.ts';
@Component({
templateUrl:"home.html",
providers: [{ provide: MY_CONFIG_TOKEN, useValue: MY_CONFIG }]
})
export class HomePage {
private appName: string;
private endPoint: string;
constructor(@Inject(MY_CONFIG_TOKEN) private config: ApplicationConfig) {
this.appName = config.appName;
this.endPoint = config.apiEndpoint;
}
}
Note how you should include it in the providers
array and specify how the injector should retrieve the instance of the config object.
providers: [{ provide: MY_CONFIG_TOKEN, useValue: MY_CONFIG }]
Update:
OpaqueToken
has been deprecated since v4.0.0 due to its lack of type support. It is recommended to use InjectionToken<?>
instead.
Replace the previous lines with:
import { InjectionToken } from '@angular/core';
// Create a config token to avoid naming conflicts
export const MY_CONFIG_TOKEN = new InjectionToken<ApplicationConfig>('config');