通过映射将类型(接口)强制转换为可观察

Tim*_*thy 4 observable typescript angular

我一直在用Angular学习TypeScript。目前,我停留在这一刻。以前,我使用订阅方法,并且一切都可以正常工作,但不是我决定使用异步管道重写代码,但这只是行不通。

  1. RestAPI拒绝特定格式的请求

export interface responseFormat {
  success: boolean;
  data: any;
}
Run Code Online (Sandbox Code Playgroud)

  1. 返回的数据可以是不同的类型。在这种情况下,数据返回餐厅对象...也可能是不同对象的数组...

export interface restaurant {
  _id: string;
  name: string;
  description: string;
  images: file[];
  cuisines: cuisine[];
  blocked: boolean;
  created: Date;
  business_hours: object;
}
Run Code Online (Sandbox Code Playgroud)

  1. 以前,我使用以下代码(它可以正常工作):

/* Provider */

getRestaurant(): Observable<responseFormat> {
  return this.http.get<responseFormat>(environment.api + "/restaurant");
}

/* Component */

private restaurant: restaurant;

getRestaurant() {
  this.restaurantProvider.getRestaurant().subscribe(res => {
    if (res.success) this.restaurant = res.data;
  });
}
Run Code Online (Sandbox Code Playgroud)

结果是分配了变量的类型。...但是我不想保留订阅记录,因此我想使用Angular异步管道来转换代码...这就是我所做的... 它不起作用

/* Provider */
getRestaurant(): Observable<responseFormat> {
  return this.http.get<responseFormat>(environment.api + "/restaurant");
}

/* Component */
private restaurantObservable: Observable<restaurant>;

getRestaurant() {
  this.restaurantObservable = this.restaurantProvider.getRestaurant().map(res => <restaurant>res.data);
  // or //
  this.restaurantObservable = this.restaurantProvider.getRestaurant().map(res => res.data as restaurant);
}
Run Code Online (Sandbox Code Playgroud)

但是上面的代码没有将响应的类型强制转换为接口...

我究竟做错了什么???

换句话说,我可以在模板中获取Observable变量(使用https://angular.io/api/common/AsyncPipe >就像这样:

/* Provider */
getRestaurant(): Observable<responseFormat> {
  return this.http.get<responseFormat>(environment.api + "/restaurant");
}

/* Component */
private restaurantObservable: Observable<restaurant>;

getRestaurant() {
  this.restaurantObservable = this.restaurantProvider.getRestaurant().map(res => res.data as restaurant);
}

/* Template */
<div class="name">{{ (restaurantObservable | async)?.name }}</div>
// or //
<div *ngIf="restaurantObservable | async as restaurant">
  <div>{{ restaurant.name }}</div>
</div>
Run Code Online (Sandbox Code Playgroud)

但是我无法在组件中获得可观察餐厅的属性。例如,this.restaurant.cuisines 抛出错误“ Observable类型不存在属性美食”

Jet*_*eto 6

为什么不直接Observable<restaurant>从您的服务中退回?

getRestaurant(): Observable<restaurant> {
  return this.http.get<responseFormat>(environment.api + "/restaurant")
    .map((response: responseFormat) => response.data as restaurant);
}
Run Code Online (Sandbox Code Playgroud)

然后在组件端:

getRestaurant() {
  this.restaurantProvider.getRestaurant().subscribe((res: restaurant) => {
    this.restaurant = res;
  });
}
Run Code Online (Sandbox Code Playgroud)

错误处理(success标志,HTTP错误等)可以通过HTTP Interceptor进行处理。

  • @Timothy你为什么不订阅?您必须先订阅观察数据,然后才能访问它。使用上面的代码,`this.restaurant`是一个实际的`restaurant`实例,您可以使用它来获取`this.restaurant.cuisines`。 (2认同)