Using Azure’s Application Settings allows you to manage different configurations for each development slot but there is no default way to utilise this feature from an Angular app. By Utilising Slot Specific settings we are able to provide different APIAn API is an Application Programming Interface. APIs are used to allow systems to retrieve data from other systems. It... URL’s for our test and staging slot, among other app-specific settings. Normally these would be maintained within the code base.
Angular is unable to access Application settings as it cannot access the Windows AzureAzure is a cloud platform by Microsoft that provides you with many different services that you can consume on a... Web Sites configuration store. A way around this is to use PHP to access those values. In searching for a solution we stumbled upon this Stack Overflow post, which suggests using a PHP file to read the values and return a JSONJSON stands for JavaScript Object Notation. It is a human-readable structure that allows data to be transmitted between software systems.... object via a GET Request. We modified it to only return application settings that are prefixed with “NG_”, this allows us to only return the settings that we define within the Application Settings that are relevant to Angular.
Our App settings look like this
And our PHP code looks like this:
$appSettings = []; foreach ($_SERVER as $key => $value) { // only look for app settings that prefixed with NG_ // NG_ denotes settings we want visible within our angular app if(preg_match('/^APPSETTING_NG_/', $key)) { $appSettings[str_replace('APPSETTING_NG_', '', $key)] = json_encode($value); } } header('Content-Type: application/json'); echo json_encode($appSettings);
In the code above, we search for “APPSETTING_NG_” as all environment variables are present in $_SERVER and Application settings are prefixed with “APPSETTING_”
To utilise the object returned via the GET call we added a new APP_INITIALIZER within app.module.ts that uses a factory to load our application settings from the PHP file
providers: [ . . . { provide: APP_INITIALIZER, useFactory: configLoader, deps: [AppSettingsService], multi: true }, . . ]
We then define a “configLoader” factory which returns the result of our appSettingService’s load method
export function configLoader(appSettingsService: AppSettingsService) { return () => appSettingsService.load(); }
Our appSettings.service.ts contains default settings if we are unable to load the PHP file, this occurs locally when developing as we do not host our Angular app within a PHP server. The load method returns a promise and only resolves it once we have received data, this allows it to hold the startup of the application until we have our settings specified and resolved the promise.
export class AppSettingsService extends BaseDataService { appSettings: AppSettings; constructor( @Inject(BASE_HTTP) private http) { super(); this.appSettings = null; } setDebugSettings() { if (environment.envName === 'uiTests') { this.appSettings = new AppSettings({ // when building the solution in uiTest mode we specify different settings baseApiUrl: '', }); } else { this.appSettings = new AppSettings({ // specify default debug settings baseApiUrl: '', }); } } load() { return new Promise((resolve) => { this.http.get('/assets/appSettings.php') .map((res: any) => { // if we have a php tag then we are in the local where it's not served if (res.text().indexOf('<?php') > -1 || res.text().indexOf('<html>') > -1) { this.setDebugSettings(); } else { let body; // check if empty, before calling json on the result if (res.text()) { body = res.json(); } this.appSettings = new AppSettings(body, true); return body || {}; } }) .subscribe(config => { resolve(); }); }); } }
We then use the AppSettingsService throughout our application by having it injected into any component that needs it.
The code can be extended to include some authorisation within the PHP to only return the JSONJSON stands for JavaScript Object Notation. It is a human-readable structure that allows data to be transmitted between software systems.... object if the request is trusted.