herrsiim
herrsiim

Reputation: 147

RxJS forkJoin handle error on route resolve

I can't seem to figure out a way to catch/handle errors inside forkJoin while trying to do route resolve.

I've created a route resolver for Account page and It should return 2 requests before routing. Now here is the part I cant work out: If user doesn't have a subscription then 404 is returned from server. I would like to handle this and if it happens, user should be routed to a different page, from where he could make subscription.

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()
        ]);
    };
}

How do I catch and handle error 404 sent by server when getUserSubscriptions() is requested?

Upvotes: 5

Views: 7473

Answers (2)

seidme
seidme

Reputation: 13048

You can catch the error, and redirect to desired route as follows:

@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);
                })
        ]);
    };
}

This way, the error is handled, but also returned to the resolve method in its original shape, so the resolver can reject access to the previously targeted route (any failed request within the forkJoin will lead to failing the forkJoin itself by default).

Upvotes: 4

martin
martin

Reputation: 96889

This depends where the error happens which is not entire obvious from your example.

If the getUserSubscriptions() call emits an error then you need to catch it before passing this to forkJoin because otherview the forkJoin will reemit the error. Also note that forkJoin requires each source Observable to emit at least one value. This is why I can't use Observable.empty() and I need to use for example Observable.of(null).

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

This will just replace the error with null so you can handle it in the subscriber to the forkJoin.

Upvotes: 5

Related Questions