refactor: initialize config via APP_INITIALIZER

Closes #181
This commit is contained in:
Jovan Krunić
2022-02-09 20:43:08 +01:00
parent 411e0970b8
commit bde0df219c
9 changed files with 37 additions and 72 deletions

View File

@@ -23,7 +23,7 @@ import {ConfigProvider} from '../../config/config.provider';
styleUrls: ['about-page.scss'],
})
export class AboutPageComponent implements OnInit {
content: Promise<SCAboutPage>;
content: SCAboutPage;
constructor(
private readonly route: ActivatedRoute,
@@ -33,12 +33,11 @@ export class AboutPageComponent implements OnInit {
async ngOnInit() {
const route = this.route.snapshot.url.map(it => it.path).join('/');
this.content = new Promise(resolve => {
this.configProvider
.getValue('aboutPages')
.then(value =>
resolve((value as SCAppConfiguration['aboutPages'])[route] ?? {}),
);
});
this.content =
(
this.configProvider.getValue(
'aboutPages',
) as SCAppConfiguration['aboutPages']
)[route] ?? {};
}
}

View File

@@ -19,7 +19,7 @@
<ion-menu-button></ion-menu-button>
<ion-back-button></ion-back-button>
</ion-buttons>
<ion-title *ngIf="content | async as content; else titleLoading">{{
<ion-title *ngIf="content; else titleLoading">{{
'title' | translateSimple: content
}}</ion-title>
<ng-template #titleLoading>
@@ -29,7 +29,7 @@
</ng-template>
</ion-toolbar>
</ion-header>
<ion-content *ngIf="content | async as content">
<ion-content *ngIf="content">
<about-page-content
*ngFor="let element of content.content"
[content]="element"

View File

@@ -107,7 +107,6 @@ describe('ConfigProvider', () => {
expect(storageProviderSpy.has).toHaveBeenCalled();
expect(storageProviderSpy.get).toHaveBeenCalledTimes(0);
expect(configProvider.client.handshake).toHaveBeenCalled();
expect(configProvider.initialised).toBe(true);
expect(await configProvider.getValue('name')).toEqual(
sampleIndexResponse.app.name,
);
@@ -129,7 +128,6 @@ describe('ConfigProvider', () => {
expect(error).toEqual(new ConfigFetchError());
expect(storageProviderSpy.has).toHaveBeenCalled();
expect(storageProviderSpy.get).toHaveBeenCalled();
expect(configProvider.initialised).toBe(true);
expect(await configProvider.getValue('name')).toEqual(
sampleIndexResponse.app.name,
);

View File

@@ -50,21 +50,16 @@ export class ConfigProvider {
*/
config: SCIndexResponse;
/**
* First session indicator
*/
firstSession = true;
/**
* Initialised status flag of config provider
*/
initialised = false;
/**
* Version of the @openstapps/core package that app is using
*/
scVersion = packageJson.dependencies['@openstapps/core'];
/**
* First session indicator (config not found in storage)
*/
firstSession = true;
/**
* Constructor, initialise api client
*
@@ -100,17 +95,7 @@ export class ConfigProvider {
*
* @param attribute requested attribute from app configuration
*/
public async getValue(attribute: keyof SCAppConfiguration) {
if (!this.initialised) {
try {
await this.init();
} catch (error) {
// don't throw ConfigFetchError if saved config is available
if (error.name === 'ConfigFetchError' && !this.initialised) {
throw error;
}
}
}
public getValue(attribute: keyof SCAppConfiguration) {
if (typeof this.config.app[attribute] !== 'undefined') {
return this.config.app[attribute];
}
@@ -138,12 +123,10 @@ export class ConfigProvider {
async init(): Promise<void> {
let loadError;
let fetchError;
this.initialised = false;
// load saved configuration
try {
this.config = await this.loadLocal();
this.firstSession = false;
this.initialised = true;
this.logger.log(`initialised configuration from storage`);
if (this.config.backend.SCVersion !== this.scVersion) {
loadError = new WrongConfigVersionInStorage(
@@ -159,7 +142,6 @@ export class ConfigProvider {
try {
const fetchedConfig: SCIndexResponse = await this.fetch();
await this.set(fetchedConfig);
this.initialised = true;
this.logger.log(`initialised configuration from remote`);
} catch (error) {
fetchError = error;
@@ -169,7 +151,7 @@ export class ConfigProvider {
throw new ConfigInitError();
}
if (typeof loadError !== 'undefined') {
throw loadError;
this.logger.warn(loadError);
}
if (typeof fetchError !== 'undefined') {
throw fetchError;
@@ -182,7 +164,6 @@ export class ConfigProvider {
* @throws SavedConfigNotAvailable if no configuration could be loaded
*/
async loadLocal(): Promise<SCIndexResponse> {
await this.storageProvider.init();
// get local configuration
if (await this.storageProvider.has(STORAGE_KEY_CONFIG)) {
return this.storageProvider.get<SCIndexResponse>(STORAGE_KEY_CONFIG);

View File

@@ -13,7 +13,6 @@
* this program. If not, see <https://www.gnu.org/licenses/>.
*/
import {CommonModule} from '@angular/common';
import {APP_INITIALIZER, NgModule} from '@angular/core';
import {FormsModule} from '@angular/forms';
import {RouterModule, Routes} from '@angular/router';
import {LeafletModule} from '@asymmetrik/ngx-leaflet';
@@ -34,6 +33,7 @@ import {MapPageComponent} from './page/map-page.component';
import {MapListModalComponent} from './page/modals/map-list-modal.component';
import {MapSingleModalComponent} from './page/modals/map-single-modal.component';
import {MapItemComponent} from './item/map-item.component';
import {NgModule} from '@angular/core';
/**
* Initializes the default area to show in advance (before components are initialized)
@@ -86,12 +86,6 @@ const mapRoutes: Routes = [
DataProvider,
DataFacetsProvider,
StAppsWebHttpClient,
{
provide: APP_INITIALIZER,
multi: true,
deps: [ConfigProvider, MapProvider],
useFactory: initMapConfigFactory,
},
],
})
export class MapModule {}

View File

@@ -26,6 +26,7 @@ import {divIcon, geoJSON, icon, LatLng, Map, marker, Marker} from 'leaflet';
import {DataProvider} from '../data/data.provider';
import {MapPosition, PositionService} from './position.service';
import {hasValidLocation} from '../data/types/place/place-types';
import {ConfigProvider} from '../config/config.provider';
/**
* Provides methods for presenting the map
@@ -107,7 +108,12 @@ export class MapProvider {
constructor(
private dataProvider: DataProvider,
private positionService: PositionService,
) {}
private configProvider: ConfigProvider,
) {
this.defaultPolygon = this.configProvider.getValue(
'campusPolygon',
) as Polygon;
}
/**
* Provide the specific place by its UID
@@ -128,7 +134,7 @@ export class MapProvider {
/**
* Provide places (buildings and canteens) const result = await this.dataProvider.search(query);
*
* @param contextFilter Additional contextual filter (e.g. from the context menu)
* @param queryText Query (text) of the search query

View File

@@ -333,9 +333,9 @@ export class SettingsProvider {
*/
public async init(): Promise<void> {
try {
const settings: SCSetting[] = (await this.configProvider.getValue(
const settings: SCSetting[] = this.configProvider.getValue(
'settings',
)) as SCSetting[];
) as SCSetting[];
for (const setting of settings) this.addSetting(setting);
for (const category of Object.keys(this.settingsCache)) {