首页 > 解决方案 > 在 Angular 上订阅 2 种类型的 observable

问题描述

抱歉标题,但我找不到更好的标题。

我正在调用一个 HTTP API,它在发送 GET 命令时返回一个 json 对象,但如果找不到资源,它将返回 404。我正在使用 Angular 9,我正在尝试找到一种方法来从服务中输出 json 对象,或者在同一个 Observable 上返回接收到的 HTTP 错误的枚举值。

请看下面的一些代码:

设备服务.ts

getDevice(objectID: number | string): Observable<Device | ResponseStatus> {
    return this.http.get<Device>(`http://localhost:8080/Registration/Device/${objectID}`)
      .pipe(
        catchError(this.handleError)
      );
  }
handleError(error: HttpErrorResponse): Observable<ResponseStatus> {
    switch (error.status) {
      case 404: {
        return of(ResponseStatus.objectNotFound);
        break;
      }
      case 409: {
        return of(ResponseStatus.objectAlreadyExists);
        break;
      }
    }
  }

我希望将 ResponseStatus 返回给我的组件,因此我可以以相同的方式处理所有错误。

设备项目解析器服务.ts

export class DeviceItemResolverService implements Resolve<Device> {

  constructor(private ds: DeviceService, private router: Router) { }
  
  resolve(route: ActivatedRouteSnapshot, state: RouterStateSnapshot): Observable<Device> | Observable<never> {

    let objectID = route.paramMap.get('objectID');

    return this.ds.getDevice(objectID).pipe(
      take(1),
      mergeMap(
        (item: Device) => {
          if (item) {
            return of(item);
          }
          else {
            this.router.navigate(['/devices']);
            return EMPTY;
          }
        }
      )
    );
  }
}

显然一切都很顺利。运行程序我可以接收设备,但我找不到在解析器上处理 ResponseStatus 的方法。

拜托,你能帮帮我吗?

标签: angulartypescripthttprxjsangular-observable

解决方案


mergeMap不需要使用,因为map在这种情况下应该足够好。

import { map } from 'rxjs/operators';
....
return this.ds.getDevice(objectID).pipe(
      take(1),
      map(
        (item: Device | ResponseStatus) => {
          // this if statement I think is the culprit.
          // Basically ResponseStatus.objectNotFound is true and it goes here
          // I am not sure if instanceof will work but basically you have to find out 
          // if you're getting Device or ResponseStatus and act accordingly
          if (item instanceof Device) {
            return item;
          }
          else {
            this.router.navigate(['/devices']);
            return null;
          }
        }
      )
    );

推荐阅读