I've encountered an issue with my service that loads a configuration object in memory based on the environment file. The problem is that the settings are read asynchronously, causing the application to start before all settings are loaded and resulting in a crash. Is there a way to ensure that these functions are awaited before completing dependency injection?
Below is my service :
import { Injectable } from '@angular/core';
import { IAppConfig } from '../models/app-config.model';
@Injectable()
export class AppConfig {
settings: IAppConfig;
version: any;
constructor() {
this.loadConfig();
}
// reads env.json file
// loads config setting based on environmental variations
public loadConfig() {
return new Promise((resolve, reject) => {
const envFile = '/env.json';
this.readJsonFile(envFile).
then((envData) => {
const configFile = `assets/appconfigs/config.${envData.env}.json`;
this.version = envData.version;
this.readJsonFile(configFile).
then((configsettings) => {
this.settings = configsettings;
resolve(this.settings);
});
});
});
}
// reads json file and returns the json object promise
public readJsonFile(jsonUrl: string): any {
return new Promise((resolve, reject) => {
let retObject: any;
const xhr = new XMLHttpRequest();
xhr.overrideMimeType('application/json');
xhr.open('GET', jsonUrl, true);
xhr.onreadystatechange = () => {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
retObject = JSON.parse(xhr.responseText);
resolve(retObject);
} else {
reject(`Could not load file '${jsonUrl}': ${xhr.status}`);
}
}
};
xhr.send(null);
});
}
}
I need the settings object to be fully loaded before the application starts. One solution was to make the class static and call loadConfig, but that's problematic for testing environments. Is there a specific way to specify when providing the service in the module to address this?