* ngIf с несколькими переменными async pipe

Попытка объединить две наблюдаемые в один *ngIf и показать пользовательский интерфейс, когда оба *ngIf.

Возьмите:

<div *ngIf="{ language: language$ | async, user: user$ | async } as userLanguage">
    <b>{{userLanguage.language}}</b> and <b>{{userLanguage.user}}</b>
</div>

От: помещение двух асинхронных подписок в один оператор Angular * ngIf

Это работает, насколько это компилируется, однако в моем случае language$ и user$ будут из двух HTTP-запросов, и кажется, что user$ выдает ошибки времени выполнения, такие как TypeError: _v.context.ngIf.user is undefined.

По сути, я действительно хочу (это не работает):

<div *ngIf="language$ | async as language && user$ | async as user">
    <b>{{language}}</b> and <b>{{user}}</b>
</div>

Это лучшее решение:

  • Подписаться внутри компонента и писать в переменные
  • Чтобы объединить две наблюдаемые внутри компонента, скажем, с помощью withLatestFrom
  • Добавить нулевые проверки {{userLanguage?.user}}

Ответ 1

Это условие должно быть обработано с помощью вложенных директив ngIf:

<ng-container *ngIf="language$ | async as language">
  <div *ngIf="user$ | async as user">
    <b>{{language}}</b> and <b>{{user}}</b>
  </div>
<ng-container>

Недостатком является то, что HTTP-запросы будут выполняться последовательно.

Чтобы выполнять их одновременно и по-прежнему иметь language и user переменные, требуется больше вложенности:

<ng-container *ngIf="{ language: language$ | async, user: user$ | async } as userLanguage">
  <ng-container *ngIf="userLanguage.language as language">
    <ng-container *ngIf="userLanguage.user as user">
      <div><b>{{language}}</b> and <b>{{user}}</b></div>
    </ng-container>
  </ng-container>
</ng-container>

Более эффективный способ сделать это - переместить логику из шаблона в класс компонента на этом этапе и создать одну наблюдаемую, например, с помощью withLatestFrom

Ответ 2

Это зависит от того, что вы хотите, но я думаю, что оператор forkJoin с загруженным флагом может быть хорошей идеей.

https://www.learnrxjs.io/operators/combination/forkjoin.html

ForkJoin ждет, когда все Observable будут завершены, чтобы вернуть свои значения в подписку

Observable.forkJoin(
  Observable.of("my language").delay(1000),
  Observable.of("my user").delay(1000),
).subscribe(results => {
  this.language = results[0]
  this.user = results[1]
})

Вы можете отлавливать ошибки в onError подписки и отображать ее.