retryWhen оператор с горячей наблюдаемой в RxJS - PullRequest
0 голосов
/ 11 февраля 2019

Требуется получить новое значение после истечения срока действия токена аутентификации и при этом сохранять его горячим.В идеале в одной наблюдаемой переменной (без отдельного субъекта)

В настоящее время код выглядит следующим образом:

constructor(private angularFireAuth: AngularFireAuth) {}

private getAuthTokenResult(): Observable<firebase.auth.IdTokenResult> {
  return this.angularFireAuth.authState.pipe(
    switchMap(user => {
      if (user) {
        return from(user.getIdTokenResult(true));
      } else {
        return of(null);
      }
    })
  );
}

public authToken$: Observable<string> = this.getAuthTokenResult().pipe(
  map((result: firebase.auth.IdTokenResult) => {
    if (new Date() >= new Date(result.expirationTime)) {
      throw new Error('Token Expired');
    } else {
      return result.token;
    }
  }),
  retryWhen(errors =>
    errors.pipe(
      tap(() => console.log('Token Expired. Getting New One...')),
      delay(100),
      take(3)
    )
  ),
  shareReplay(1)
) as ConnectableObservable<string>;

Но он не выполняет свою работу после истечения срока действия токена аутентификации - это новыйодин не получен.

Вот так выглядит зависимый сервисный метод

addProduct(
  data: MerchantProductPartial
): Observable<MerchantProduct> {
  return this.authService.authToken$.pipe(
    switchMap(token => {
      // console.log('_addProduct', token);
      if (token) {
        const endpoint = ``;
        const httpOptions = {
          headers: new HttpHeaders({
            'Authorization': `Bearer ${token}`,
          })
        };
        return this.http.post(endpoint, data, httpOptions);
      }
      else {
        throw new Error('Authorization Token not provided.');
      }
    })
  );
}

, а выполнение метода выглядит следующим образом

this.merchantService.addProduct({
      name: 'New Test Product'
    }).pipe(take(1)).subscribe(res => console.log('res:', res), err => console.log('err:', err))

РЕШЕНИЕ :

Если кого-то волнует решение - оно проще, чем я думал.Просто нужно использовать другой метод https://firebase.google.com/docs/reference/js/firebase.User#getIdToken, который автоматически обновляет недействительные токены ... Только не заставляйте его обновить ...

public authToken$: Observable<string> = this.angularFireAuth.authState.pipe(
  switchMap(user: firebase.User => {
    if (user) {
      return from(user.getIdToken());
    } else {
      return of(null);
    }
  })
);
...