fbpx

Azure Application settings and Angular

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 API 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 Azure 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 JSON 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

azure application settings angular

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 JSON object if the request is trusted.

2 thoughts on “Azure Application settings and Angular”

  • Hala says:

    Thanks for sharing your solution .. After following your solution it works fine in local ‘serve’ but when deployed to IIS, it doesn’t work “php file not found”.

    So I was wondering where does that php code run ? in client browser or server side ?

    • Anthony Sapountzis says:

      Hi Hala,
      The IIS server needs to be able to host PHP files. When we run in development we get a 404 not found error and cater for that in debug mode. When we run this in production we have the file hosted in the Azure App Service which can then be used and accessed the files.

Leave a Reply