Пытаюсь получить Observable<boolean>
для моего Стража, объединив два значения Observable<boolean>
через forkJoin
.
Я пробовал этот подход раньше:
isAllowedToEditSession(sessionId: number): Observable<boolean> {
const isAllowed$: BehaviorSubject<boolean> = new BehaviorSubject(false);
const hostName = this.authService.getMyDisplayName();
this.sessionProxyService.getSessionById(sessionId).subscribe(session => {
if (session.hostName === hostName) {
isAllowed$.next(true);
}
});
this.userService.isUserAdmin().subscribe(isAdmin =>
isAllowed$.next(isAdmin));
return isAllowed$.asObservable();
}
Это сработало, но только потому, что this.userService.isUserAdmin()
— это BehaviorSubject
и у него уже было сохранено значение, поэтому он выполнялся синхронно.
Это мой текущий подход, который не дает мне того результата, на который я надеялся.
isAllowedToEditSession(sessionId: number): Observable<boolean> {
const hostName = this.authService.getMyDisplayName();
const isAllowed$ = forkJoin(
this.sessionProxyService.getSessionById(sessionId),
this.userService.isUserAdmin()
).pipe(
map(([session, isAdmin]) => {
const isHost = session.hostName === hostName;
console.info(isHost || isAdmin);
return isHost || isAdmin;
})
);
return isAllowed$;
}
isAllowed$
распознается как Observable<boolean>
, но неправильно выдает эти значения.
ОБНОВИТЬ
Это работает (см. принятый ответ для объяснения):
isAllowedToEditSession(sessionId: number): Observable<boolean> {
const hostName = this.authService.getMyDisplayName();
const isAllowed$ = forkJoin(
this.sessionProxyService.getSessionById(sessionId), //pipe(take(1)) not needed here
this.userService.isUserAdmin().pipe(take(1))
).pipe(
map(([session, isAdmin]) => {
const isHost = session.hostName === hostName;
return isHost || isAdmin;
})
);
return isAllowed$;
}
Извините, я должен был указать ожидаемое поведение. Это не работает, потому что не выдает true, хотя либо isHost
, либо isAdmin
должны возвращать true в моем случае использования. Но принятый ответ был решением моей проблемы.
forkJoin
требует, чтобы все исходные Observable выдавали хотя бы одно значение, а затем завершались. И это проблема у вас есть. Вы используете BehaviorSubject
внизу, что не завершается, пока вы не вызовете .complete()
на нем.
Вы должны сделать, например, это:
if (session.hostName === hostName) {
isAllowed$.next(true);
isAllowed$.complete();
}
Так что это зависит от того, как реализованы getSessionById()
и isUserAdmin()
. Вы также можете передать их обоих с помощью take(1)
, прежде чем передавать их в forkJoin
.
Спасибо! Это была моя проблема. Однако у меня есть вопрос: автоматически ли завершаются http-вызовы? Потому что мне не нужно было .pipe(take(1))
на this.sessionProxyService.getSessionById(sessionId)
, что является вызовом. Я обновил свой пост с окончательным решением.
Да, если вы имеете в виду HttpClient
в Angular, они выполняются автоматически.
Как это не работает? Вы получаете сообщение об ошибке?