Angular 11 site. I've searched all over but I'm still struggling with what seems like it should be a pretty common scenario.
Goal: Do an http call to retrieve a list of items, then do another http call to retrieve details for the first item. After both calls are done (whether they succeeded or failed), hide the component's overall wait indicator.
Here is a highly simplified version without null-checking and error handling:
ngOnInit(): void {
this.getPackages();
}
private getPackages() {
this._packageSubscription = this.packageService.getPackages()
.pipe(
finalize(() => {
console.log('getPackages finalize');
this.loadingPackages = false; //hide wait indicator: happens BEFORE getPackageDetails is finished
})
)
.subscribe(
packages => {
this.packageOptions = packages;
this.selectedPackage = packages[0];
this.loadSelectedPackage();
}
);
}
public loadSelectedPackage() {
this._packageDetailsSubscription = this.packageService.getPackageDetails(this.selectedPackage!.Id)
.pipe(
finalize(() => {
console.log('getPackageDetails finalize');
})
)
.subscribe(
packageDetails => {
this.packageDetails = packageDetails;
}
);
}
When executed, the console reads:
getPackages finalize
getPackageDetails finalize
I would expect it the other way around.
I'm aware I could add my code to deactivate the wait indicator in the inner finalize()
for getPackageDetails()
, but there are a few issues with that:
- It just seems wrong. Why can't I know when the chain is complete at the outer level?
- That would only cover the case where everything succeeded. I'd have to add a second line of code somewhere to hide the wait indicator when something with the first call failed.
loadSelectedPackage()
can be called again later after a user action changes the selected package, so it makes even less sense for it to deal with something that is only relevant on the initial load.
So why doesn't my outer finalize()
wait until the chain is complete? Or how else can I know when the chain is complete?