处理Resolve服务中的错误

时间:2016-11-08 14:10:10

标签: angular typescript rxjs

假设我有ValuesComponent在HTML表格中显示Value数组。

// in value.ts
export class Value { ... }
// in values.component.ts
@Component(...)
export class ValuesComponent { ... }

作为一名优秀的程序员,我创造了一个不同的类,负责提供价值。我们称之为ValuesService

// in values.service.ts
@Injectable()
export class ValuesService
{
    public getValues(): Observable<Value[]>
    {
       ...
    }
}

假设服务从Web服务获取其值:/api/values

现在我不想将服务直接注入到我的组件中,而是让Angular路由器在导航到组件之前预先获取值。

为此,我创建了一个Resolve服务类并将其插入路由器模块。

// in values-resolver.service.ts
export class ValuesResolverService implements Resolve<Value[]> {
    constructor(private backend: ValuesService) {
    }

    public resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Value[]> {
        return this.backend.getValues();
    }
}
// In app.module.ts (in @NgModule())
imports: [
  RouterModule.forRoot([{
    path: 'values',
    component: ValuesComponent,
    resolve: { values: ValuesResolverService }
  }])
]
// In values.component.ts
public values: Value[];

constructor(private route: ActivatedRoute) {
}

ngOnInit() {
    this.values = route.data.values as Value[];
}

到目前为止我怎么做?好?那么当ValuesService.getValues()失败时,我在哪里进行错误处理? (连接错误,内部服务器错误,......)

当用户尝试导航到/#/values路由并发生错误时,我想将错误记录到控制台并停止导航。理想情况下,我想将用户重定向到/#/error路由(示例代码中未显示)。

1 个答案:

答案 0 :(得分:3)

在这种情况下,服务应该处理错误,并重定向到所需的路由。然后,catch方法应返回一个空的Observable(用于解析防护解析),同时在解析期间处理空案例。

像这样的东西

export class ValuesService {
    constructor(private http:Http, private router:Router) {}

    getValue() {
       this.http.get('/some/url').map((response:Response) => {
           // Map your response to a model here
       }).catch((response:Response) => {
           // Handler case for different status
           this.router.navigate(['/error']);
           return Observable.empty();
       })
    }
}

守卫就像下面这样

export class ValueResolveGuard implements Resolve<Value[]> {

    constructor(private valueService:ValueService) {}

    resolve() { // You don't need the route & state if you're not gonna use them
        this.valueService.getValue().toPromise().then((values:Values[]) => {
            if (!values) { // For the Observable.empty() case
                // return some default stuff
            }
            return values;
        })
    }
}

或者,如果你想特别返回一个observable(在这种情况下不应该有任何区别,因为解析守护,同时接受一个observable和一个promise),你可以这样做。

 this.valueService.getValue().first().catch({} => { 
      // return some default value.
 });

请注意,first()是必需的,因此返回的observable将是一个终止的observable,否则解析后卫将无法解析。需要捕获,因为对空observable的first()调用会引发错误。