I have the application based on Angular v4. The scenario is simple - I need to load some settings from the server before the app starts. To do so, I use the APP_INITIALIZER
:
{
provide: APP_INITIALIZER,
useFactory: init,
deps: [SettingsService],
multi: true
}
export function init(config: SettingsService) {
return () => config.load_one();
}
//import declarations
@Injectable()
export class SettingsService {
constructor(private http: HttpClient) { }
load_one(): Promise<boolean> {
return new Promise<boolean>((resolve) => {
this.http.get('url').subscribe(value => {
console.log('loadSettings FINISH');
resolve(true);
});
});
}
load_two(): Observable<any> {
const promise = this.http.get('url');
promise.subscribe(value => {
console.log('loadSettings FINISH');
});
return promise;
}
}
Somewhere in the app I have the function called manageSettings()
(its code doesn't matter at the moment) which requires that the data from the SettingsService
service is initialized.
And here's the thing - when I use the the function load_two()
, the app does'nt wait until it completes:
app-root constructor
manageSettings()
loadSettings FINISH
and when I use the function load_one()
it works fine:
loadSettings FINISH
app-root constructor
manageSettings()
can someone explain why that happens ?
Angular 12 added support for Observable
s, so this should no longer be an issue if you're using Angular 12 or newer.
The reason load_one
works and load_two
doesn't is that Angular 11 and older waits only for Promise
s; not Observable
s.
Here's the source:
if (this.appInits) { for (let i = 0; i < this.appInits.length; i++) { const initResult = this.appInits[i](); if (isPromise(initResult)) { asyncInitPromises.push(initResult); } } }
Where isPromise
is defined like this:
export function isPromise<T = any>(obj: any): obj is Promise<T> { // allow any Promise/A+ compliant thenable. // It's up to the caller to ensure that obj.then conforms to the spec return !!obj && typeof obj.then === 'function'; }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With