我正在尝试使用解析器以制作更好的UX。一切顺利,一切顺利。我似乎无法弄清楚的是如何处理异常。我的解析器调用了一个服务,该服务命中了一个webapi项目。一个例子:
FooResolver:
resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Foo> {
return this.fooService.getById(route.params['id']).catch(err => {
****not sure what to do/return in the case of a server error****
return Observable.throw(err);
});
}
FooService:
public getById(id: string): Observable<Foo> {
return this.http.get(`${ this.apiUrl }/${ id }`)
.map(this.extractData)
.catch(this.handleError);
}
handleError函数:
protected handleError (error: Response | any) {
// Todo: Log the error
// Errors will be handled uniquely by the component that triggered them
return Observable.throw(error);
}
在FooComponent内,我这样做(如果从服务/解析器返回错误,则永远不会发生):
FooComponent:
ngOnInit(): void {
this.foo= this.route.snapshot.data['foo'];
if (this.foo) {
this.createForm(this.foo);
}
}
我尝试抛出错误(如图所示)-我在控制台中收到此异常:
未捕获(承诺):状态响应:500内部服务器URL错误:
然后返回new Observable<Foo>()
,得到:
无法读取未定义的属性“订阅”
我有几个解析器,所有解析器都可以在服务器上遇到异常,但是我不知道如果发生这些异常该怎么办。
这是我使用Gunter建议的技术的一个带有错误处理的解析器的示例:
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<IProduct> {
constructor(private productService: ProductService,
private router: Router) { }
resolve(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<IProduct> {
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);
});
}
}
您可以在此处找到完整的示例:APM-final文件夹中的https://github.com/DeborahK/Angular-Routing。
更新2019年2月
对于解析程序中的错误处理,这是一个更好的答案:
1)将您的界面包装在另一个具有可选错误属性的界面中:
/* 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;
}
2)解析到该界面:
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<ProductResolved> {
constructor(private productService: ProductService) { }
resolve(route: ActivatedRouteSnapshot,
state: RouterStateSnapshot): Observable<ProductResolved> {
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 });
})
);
}
}
3)在组件中,拉出您需要的一部分接口:
ngOnInit(): void {
const resolvedData: ProductResolved =
this.route.snapshot.data['resolvedData'];
this.errorMessage = resolvedData.error;
this.product = resolvedData.product;
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句