phase-4: add provider-abstracted ConfigService with mock bootstrap loader
This commit is contained in:
16
src/app/core/bootstrap/providers/api-bootstrap.provider.ts
Normal file
16
src/app/core/bootstrap/providers/api-bootstrap.provider.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { BootstrapConfig } from '../../../shared/models/config';
|
||||||
|
import { ConfigProvider } from '../../config/config-provider.interface';
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class ApiBootstrapProvider implements ConfigProvider {
|
||||||
|
private readonly bootstrapUrl = '/bootstrap';
|
||||||
|
|
||||||
|
constructor(private readonly http: HttpClient) {}
|
||||||
|
|
||||||
|
loadBootstrap(): Observable<BootstrapConfig> {
|
||||||
|
return this.http.get<BootstrapConfig>(this.bootstrapUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
16
src/app/core/bootstrap/providers/mock-bootstrap.provider.ts
Normal file
16
src/app/core/bootstrap/providers/mock-bootstrap.provider.ts
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
import { Injectable } from '@angular/core';
|
||||||
|
import { HttpClient } from '@angular/common/http';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { BootstrapConfig } from '../../../shared/models/config';
|
||||||
|
import { ConfigProvider } from '../../config/config-provider.interface';
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class MockBootstrapProvider implements ConfigProvider {
|
||||||
|
private readonly bootstrapUrl = '/assets/mock/bootstrap/bootstrap.json';
|
||||||
|
|
||||||
|
constructor(private readonly http: HttpClient) {}
|
||||||
|
|
||||||
|
loadBootstrap(): Observable<BootstrapConfig> {
|
||||||
|
return this.http.get<BootstrapConfig>(this.bootstrapUrl);
|
||||||
|
}
|
||||||
|
}
|
||||||
6
src/app/core/config/config-provider.interface.ts
Normal file
6
src/app/core/config/config-provider.interface.ts
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
import { Observable } from 'rxjs';
|
||||||
|
import { BootstrapConfig } from '../../shared/models/config';
|
||||||
|
|
||||||
|
export interface ConfigProvider {
|
||||||
|
loadBootstrap(): Observable<BootstrapConfig>;
|
||||||
|
}
|
||||||
8
src/app/core/config/config-provider.token.ts
Normal file
8
src/app/core/config/config-provider.token.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import { InjectionToken, inject } from '@angular/core';
|
||||||
|
import { ConfigProvider } from './config-provider.interface';
|
||||||
|
import { MockBootstrapProvider } from '../bootstrap/providers/mock-bootstrap.provider';
|
||||||
|
|
||||||
|
export const CONFIG_PROVIDER = new InjectionToken<ConfigProvider>('CONFIG_PROVIDER', {
|
||||||
|
providedIn: 'root',
|
||||||
|
factory: () => inject(MockBootstrapProvider)
|
||||||
|
});
|
||||||
35
src/app/core/config/config.service.ts
Normal file
35
src/app/core/config/config.service.ts
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
import { Injectable, inject } from '@angular/core';
|
||||||
|
import { Observable, throwError } from 'rxjs';
|
||||||
|
import { catchError, shareReplay, tap } from 'rxjs/operators';
|
||||||
|
import { BootstrapConfig } from '../../shared/models/config';
|
||||||
|
import { CONFIG_PROVIDER } from './config-provider.token';
|
||||||
|
|
||||||
|
@Injectable({ providedIn: 'root' })
|
||||||
|
export class ConfigService {
|
||||||
|
private readonly provider = inject(CONFIG_PROVIDER);
|
||||||
|
|
||||||
|
private bootstrapSnapshot: BootstrapConfig | null = null;
|
||||||
|
private bootstrap$?: Observable<BootstrapConfig>;
|
||||||
|
|
||||||
|
loadBootstrap(forceRefresh: boolean = false): Observable<BootstrapConfig> {
|
||||||
|
if (!this.bootstrap$ || forceRefresh) {
|
||||||
|
this.bootstrap$ = this.provider.loadBootstrap().pipe(
|
||||||
|
tap(config => {
|
||||||
|
this.bootstrapSnapshot = config;
|
||||||
|
}),
|
||||||
|
shareReplay(1),
|
||||||
|
catchError(error => {
|
||||||
|
this.bootstrap$ = undefined;
|
||||||
|
this.bootstrapSnapshot = null;
|
||||||
|
return throwError(() => error);
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.bootstrap$;
|
||||||
|
}
|
||||||
|
|
||||||
|
getBootstrapSnapshot(): BootstrapConfig | null {
|
||||||
|
return this.bootstrapSnapshot;
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user