Все, что вы возвращаете из первой mergeMap, передается во вторую mergeMap, поэтому дальнейшее распространение не будет остановлено.Если вы хотите остановить распространение, используйте фильтр (хотя это может вызвать зависание в этом сценарии).
Вы используете mergeMap только тогда, когда возвращаете Observable, но нет необходимости возвращать Observable из 2-го mergeMap.Просто сделайте:
.mergeMap((isRoleAuthenticated: boolean) => {
if (isRoleAuthenticated) {
return Observable.of(true)
}
return this.auth.isRole(Roles.DEFAULT_USER)
})
.tap((isDefaultUser: boolean) => {
if (isDefaultUser) {
this.router.navigate(['SOMEWHERE'])
} else {
this.router.navigate(['SOMEWHERE_ELSE'])
}
})
.map((isDefaultUser: boolean) => {
return false
})
Кроме того, вы используете синтаксис RxJs v5, но вы должны использовать v6.В v6 операторы - mergeMap, tap, map - разделяются запятой в трубе.
Возможно, навигация маршрутизатора препятствует окончательному возврату и вызывает зависание?Прокомментируйте это и посмотрите, не остановит ли это зависание.
Не уверен, что это полностью исправит ваш пробел, но, надеюсь, некоторые полезные идеи за 1 час
1011 * Я предполагаю, что эти возвращаемые Observables:
- this.auth.isRoleAuthenticated
- this.auth.isRole (Roles.DEFAULT_USER)
Если этого не произойдет, у вас возникнут проблемы.
Solution
Вместо того, чтобы сосредоточиться на остановке цепочки, вы можете создать объект, состоящий из результатов собранных Observables по пути, и распространять его дальше, что решает проблему:
canActivate(route: ActivatedRouteSnapshot): Observable<boolean> | boolean {
return this.auth.getRole()
.mergeMap((role: string) => {
return this.auth.isRoleAuthorized(route.data.roles)
.map((authorized: boolean) => ({
role: role,
authorized: authorized
}));
})
.do((markers: { role: string, authorized: boolean }) => {
const redirectUrl: string = markers.role === Roles.DEFAULT_USER ? 'SOMEWHERE' : 'SOMEWHERE_ELSE';
this.router.navigate([redirectUrl]);
})
.map((markers: { role: string, authorized: boolean }) => {
return markers.authorized;
});
}