【问题标题】:RxJS forkJoin handle error on route resolveRxJS forkJoin 处理路由解析错误
【发布时间】:2017-03-13 09:43:15
【问题描述】:

在尝试进行路由解析时,我似乎无法找到一种在 forkJoin 中捕获/处理错误的方法。

我为帐户页面创建了一个路由解析器,它应该在路由之前返回 2 个请求。现在这是我无法解决的部分:如果用户没有订阅,则从服务器返回 404。我想处理这个问题,如果发生这种情况,用户应该被路由到另一个页面,他可以从那里订阅。

import { Injectable } from '@angular/core';
import { Resolve, ActivatedRouteSnapshot } from '@angular/router';
import { Observable } from 'rxjs/Rx';
import { AccountService } from './account.service';

@Injectable()
export class AccountResolver implements Resolve<any> {
    constructor(private accountService: AccountService) { }

    resolve(route: ActivatedRouteSnapshot): Observable<any> {
        return Observable.forkJoin([
            this.accountService.getUser(),
            this.accountService.getUserSubscriptions()
        ]);
    };
}

当请求 getUserSubscriptions() 时,如何捕获和处理服务器发送的错误 404?

【问题讨论】:

    标签: angular rxjs observable fork-join


    【解决方案1】:

    这取决于错误发生的位置,这在您的示例中并不完全明显。

    如果getUserSubscriptions() 调用发出错误,那么您需要在将其传递给forkJoin 之前捕获它,因为其他视图forkJoin 将重新发出错误。另请注意,forkJoin 要求每个源 Observable 至少发出一个值。这就是为什么我不能使用Observable.empty() 而我需要使用例如Observable.of(null)

    return Observable.forkJoin([
        this.accountService.getUser(),
        this.accountService.getUserSubscriptions()
            .catch(err => {
                // Logic based on the err parameter
                return Observable.of(null);
            })
    ]);
    

    这只会用null 替换错误,以便您可以在forkJoin 的订阅者中处理它。

    【讨论】:

    • 只是想知道,为什么他会捕获错误并返回 Observable 呢?关键不是要成功解决路由依赖关系,而是检查 404 错误并相应地重定向..
    【解决方案2】:

    您可以捕获错误,并重定向到所需的路线,如下所示:

    @Injectable()
    export class AccountResolver implements Resolve<any> {
        constructor(private accountService: AccountService,
                    private router: Router) { }
    
        resolve(route: ActivatedRouteSnapshot): Observable<any> {
            return Observable.forkJoin([
                this.accountService.getUser(),
                this.accountService.getUserSubscriptions()
                    .catch(error => {
                        if(error.status === 404) {
                            this.router.navigate(['subscription-create']);
                        }
    
                        return Observable.throw(error);
                    })
            ]);
        };
    }
    

    这样,错误得到了处理,但也以原来的形式返回到resolve方法,因此解析器可以拒绝对先前目标路由的访问(forkJoin内的任何失败请求都将导致失败forkJoin 本身默认)。

    【讨论】:

    • 已经尝试过了,但没有帮助。我收到了这个错误:'(error: any) => void' 类型的参数不可分配给'(err: any,catch: Observable) => ObservableInput' 类型的参数。类型 'void' 不可分配给类型 'ObservableInput'。
    • 我的问题是我不知道内部捕获我必须返回。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-30
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多