Объединение наблюдаемых в цепочку и передача результата в следующий

#angular #rxjs6

#angular #rxjs6

Вопрос:

Я хочу использовать результат одной подписки для отправки другой. Каков наилучший способ сделать это в Angular 7? В настоящее время моя подписка работает с перебоями (данные пользователю не возвращаются).

 this.userService.getNumberOfUsers().subscribe(data => {
  if (data) {
    this.noOfUsers = data.data['counter'];
    this.tempRanking = this.referralService.getWaitlist().subscribe(waitlistResult => {
      if (waitlistResult amp;amp; this.userData.referralId) {
        return this.referralService.calculateRanking(this.userData.referralId, waitlistResult).then((result: number) => {
          if (result) {
            if (result > this.noOfUsers) {
              this.ranking = this.noOfUsers;
            } else {
              this.ranking = resu<
            }
          }
        });
      }
    });
  }
});
  

Ответ №1:

 this.referralService.getWaitlist().pipe(
    filter(waitlistResult  => waitlistResult != null),
    switchMap(waitlistResult  => combineLatest( this.referralService.calculateRanking(this.userData.referralId, waitlistResult ), this.userService.getNumberOfUsers())),
    filter(combined => combined[0] != null amp;amp; combined[1] != null)
).subscribe(combined =>{
    if (combined[0] > combined[1]) {
        this.ranking = combined[1].data['counter'];
    } else {
        this.ranking = combined[0];
    }
})
  

Еще лучшим способом было бы подписаться на результат в вашем шаблоне:

 public ranking$: Observable<number>;
  

 this.ranking$ = this.referralService.getWaitlist().pipe(
    filter(waitlistResult  => waitlistResult != null),
    switchMap(waitlistResult  => combineLatest( this.referralService.calculateRanking(this.userData.referralId, waitlistResult ), this.userService.getNumberOfUsers())),
    filter(combined => combined[0] != null amp;amp; combined[1] != null),
    map(combined =>{
        if (combined[0] > combined[1]) {
            return combined[1].data['counter'];
        } else {
            return combined[0];
        }
    })
);
  

 <div>{{ranking$ | async}}</div>
  

Редактировать
Я вижу, что this.referralService.calculateRanking возвращает обещание, возможно, вы захотите преобразовать это в наблюдаемое в этой функции или использовать ‘from’

 import { from } from 'rxjs';
from(this.referralService.calculateRanking(...))
  

Правка 2

 public numberOfUsers$: Observable<number>;
public ranking$: Observable<number>;
  

 this.numberOfUsers$ = this.userService.getNumberOfUsers();
this.ranking$ = this.referralService.getWaitlist().pipe(
    filter(waitlistResult  => waitlistResult != null),
    switchMap(waitlistResult  => combineLatest( from(this.referralService.calculateRanking(this.userData.referralId, waitlistResult )), this.numberOfUsers$)),
    filter(combined => combined[0] != null amp;amp; combined[1] != null),
    map(combined =>{
        if (combined[0] > combined[1]) {
            return combined[1].data['counter'];
        } else {
            return combined[0];
        }
    })
);
  

 <p style="font-size: 1.25em" *ngIf="ranking">You are in position <strong> {{ranking$ | async}}</strong> of <strong>{{ numberOfUsers$ | async }}</strong> on the waitlist.</p>
  

Комментарии:

1. Спасибо. Как бы я получил this.noOfUsers = data.data['counter']; и присвоил его переменной? Мне это нужно как отдельное значение для отображения в моем представлении: <p style="font-size: 1.25em" *ngIf="ranking">You are in position <strong> {{ ranking }}</strong> of <strong>{{ noOfUsers }}</strong> on the waitlist.</p>

2. Во-вторых, правильна ли форма моего вычисления: pastebin.com/ysFUZhz4

3. Смотрите мой edit2, не могу точно сказать о вычислении, не видя всего пути кода, но должно быть достаточно

4. Спасибо. pastebin.com/g4PZSPcb , this.userService.getNumberOfUsers() не сбой с Type 'Observable<{ data: {}; }>' is not assignable to type 'Observable<number>'. Type '{ data: {}; }' is not assignable to type 'number'.

5. Извините, что надоедаю вам!