Reputation: 2964
I want to load app settings before the Angular application starts. I copied in the code from another project but it stopped working. What is wrong?
In app.module.ts
:
providers: [
{
provide: APP_INITIALIZER,
multi: true,
deps: [AppSettingsService],
useFactory: (appSettingsService: AppSettingsService) => {
return () => {
return appSettingsService.init();
};
}
},
]
And here is the app-settings.service.ts
@Injectable({
providedIn: 'root'
})
export class AppSettingsService {
private appsettings: Appsettings;
constructor(private http: HttpClient) { }
init(): Promise<Appsettings> {
console.warn('AppSettingsService.init'); // This appears in the console.
return this.http.get<Appsettings>('appsettings.json').pipe(
tap(response => {
console.warn('AppSettingsService.init.tap'); // This does not appear in the console.
this.appsettings = response;
})
).toPromise();
}
get authority(): string {
return this.appsettings.jwtBearerSettings.authority;
}
}
class Appsettings {
baseUri: string;
angularClientApiURI: string;
jwtBearerSettings: JwtBearerSettings;
}
class JwtBearerSettings {
authority: string;
}
In the project from which this is copied I see in the browser tools a GET
request for appsettings.json
but not so in the project to which it has been copied.
Update
I have found that if I remove the AuthInterceptor
from the porviders
then it starts working.
@Injectable()
export class AuthInterceptor implements HttpInterceptor {
constructor(private authService: AuthService) { }
intercept(request: HttpRequest<unknown>, next: HttpHandler): Observable<HttpEvent<unknown>> {
return next.handle(this.addAuthenticationToken(request));
}
addAuthenticationToken(request: HttpRequest<unknown>): HttpRequest<unknown> {
const token = this.authService.access_token; // (The id_token also works but can be much larger because it contains more claims.)
if (token) {
const tokenReq: HttpRequest<any> = request.clone({
setHeaders: {
Authorization: `Bearer ${token}`
}
});
return tokenReq;
}
else {
return request;
}
}
}
Upvotes: 1
Views: 880
Reputation: 2964
The problem seems to be that the APP_INITIALIZER
is using HttpClient
which depends on HTTP_INTERCEPTORS
which thus creates a mutual dependency.
cf. https://github.com/angular/angular/issues/26845
The solution is How to make an angular module to ignore http interceptor added in a core module
which looks like this, i.e., to use HttpBackend
to construct a HttpClient
instead of having HttpClient
provided by the DI which uses the HTTP_INTERCEPTORS
.
export class AppSettingsService {
private httpClient: HttpClient;
private appsettings: Appsettings;
constructor(private httpBackend: HttpBackend) {
this.httpClient = new HttpClient(httpBackend);
}
Upvotes: 2