Any time I run into a problem that requires multiple async pipes in a single template, I combine the observables using combineLatest into a single observable.
private _selectedCountry$ = new Subject<Country>();
private _countriesLoadMoreTrigger$ = new Subject<RangeToLoad>();
private _citiesLoadMoreTrigger$ = new Subject<RangeToLoad>();
private _countryList$ = /* build your country data stream, probably using _selectedCountry$ and _countriesLoadMoreTrigger$ as source observables, likely with a switchMap() to load the requrested range */
private _cityList$ = /* build your city data stream, using _selectedCountry$ and combining it with the _citiesLoadMoreTrigger$ subject */
public viewModel$ = combineLatest([this._countryList$, this._cityList$]).pipe(
map(([countryList, cityList]) => ({
countryList,
cityList,
}))
);
Then in your template,
The template would look like this:
<ng-container ngIf="(viewModel$ | async) as viewModel">
{{country.name}}
<ulngFor="let country of viewModel.countryList; index as i">
<lingFor="let cities of viewModel.citiesList; index as i">
{{city.name}
</li>
</ul>
</ng-container>