How to handle error in a Resolver

前端 未结 3 1878
旧巷少年郎
旧巷少年郎 2021-01-30 10:46

I\'m trying to use resolvers in order to make a better UX. Everything works great on the happy path. What I can\'t seem to figure out is how to handle exceptions. My resolver ca

3条回答
  •  别那么骄傲
    2021-01-30 11:19

    Here is an example of one of my resolvers with error handling, using the technique that Gunter suggests:

    import { Injectable } from '@angular/core';
    import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot, Router } from '@angular/router';
    
    import { Observable } from 'rxjs/Observable';
    import 'rxjs/add/operator/catch';
    import 'rxjs/add/operator/map';
    import 'rxjs/add/observable/of';
    
    import { IProduct } from './product';
    import { ProductService } from './product.service';
    
    @Injectable()
    export class ProductResolver implements Resolve {
    
        constructor(private productService: ProductService,
                    private router: Router) { }
    
        resolve(route: ActivatedRouteSnapshot,
                state: RouterStateSnapshot): Observable {
            let id = route.params['id'];
            if (isNaN(+id)) {
                console.log(`Product id was not a number: ${id}`);
                this.router.navigate(['/products']);
                return Observable.of(null);
            }
            return this.productService.getProduct(+id)
                .map(product => {
                    if (product) {
                        return product;
                    }
                    console.log(`Product was not found: ${id}`);
                    this.router.navigate(['/products']);
                    return null;
                })
                .catch(error => {
                    console.log(`Retrieval error: ${error}`);
                    this.router.navigate(['/products']);
                    return Observable.of(null);
                });
        }
    }
    

    You can find the complete example here: https://github.com/DeborahK/Angular-Routing in the APM-final folder.

    UPDATE Feb 2019

    Here is a better answer for error handling in a resolver:

    1. Wrap your interface in another interface with an optional error property:
    /* Defines the product entity */
    export interface Product {
      id: number;
      productName: string;
      productCode: string;
      category: string;
      tags?: string[];
      releaseDate: string;
      price: number;
      description: string;
      starRating: number;
      imageUrl: string;
    }
    
    export interface ProductResolved {
      product: Product;
      error?: any;
    }
    
    1. Resolve to that interface:
    import { Injectable } from '@angular/core';
    import { Resolve, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
    
    import { Observable, of } from 'rxjs';
    import { map, catchError } from 'rxjs/operators';
    
    import { ProductResolved } from './product';
    import { ProductService } from './product.service';
    
    @Injectable({
      providedIn: 'root',
    })
    export class ProductResolver implements Resolve {
      constructor(private productService: ProductService) {}
    
      resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable {
        const id = route.paramMap.get('id');
        if (isNaN(+id)) {
          const message = `Product id was not a number: ${id}`;
          console.error(message);
          return of({ product: null, error: message });
        }
    
        return this.productService.getProduct(+id).pipe(
          map((product) => ({ product: product })),
          catchError((error) => {
            const message = `Retrieval error: ${error}`;
            console.error(message);
            return of({ product: null, error: message });
          }),
        );
      }
    }
    
    1. In the component, pull off the piece of the interface you need:
    ngOnInit(): void {
      const resolvedData: ProductResolved = this.route.snapshot.data['resolvedData'];
      this.errorMessage = resolvedData.error;
      this.product = resolvedData.product;
    }
    

提交回复
热议问题