Rxjs管道无法使用angular的Http.get()

问题描述 投票:3回答:1

我有一个Angular 4组件正在调用服务来获取数据。不是最奇怪的情况。检索数据后需要对其进行转换并对其进行过滤。显然,现在这样做的方法是使用管道。

在我的组件中:

ngOnInit(): void {
    this.suService.getShippingUnitTypes().subscribe(res => {
        console.log("Getting shipping unit types: ", res);
    });
}

在我的服务中:

getShippingUnitTypes(): any {
    const convertToJson = map(value => (value as any).json().XXETA_GRID_STATIC_LOV);
    const filterShippingUnit = filter(value => (value as any).LOV_TYPE == "SHIPPING_UNIT");

    return this.http.get(
        this.constantsService.LOOKUP_COLUMN_BATCH_URL
    ).pipe(convertToJson, filterShippingUnit);
}

该服务导入以下内容:

import { Injectable } from '@angular/core';
import { Http, Response, RequestOptions, Headers, RequestMethod } from '@angular/http';
import { Observable, pipe } from 'rxjs/Rx';
import { map, filter } from 'rxjs/operators';

调试时,代码永远不会出错,但根本不会访问Component中的console.log()语句。如果我删除.pipe()并简单地返回Observable,代码会记录我所期望的,而不需要转换和过滤。

我对Rxjs很新,并且使用Pipe。我显然不理解某些事情。

编辑添加信息:

我把水龙头放进管子里......

pipe(tap(console.log), convertToJson, tap(console.log), filterShippingUnit, tap(console.log))

我不知道那个水龙头存在但它很有用。前两个控制台日志给了我所期望的。第三个,就在filterShippingUnit之后,没有做任何事情。它根本不记录值。甚至不是空的。

在convertToJson之后,console.log会吐出一个包含28个对象的数组。其中一个目标是:

{LOV_TYPE: "SHIPPING_UNIT", LOV_TAB_TYP_ITEM: Array(4)}

我希望基于filterShippingUnit过滤器传递该对象。

angular typescript rxjs angular2-http rxjs-lettable-operators
1个回答
4
投票

问题最有可能在这里:

const filterShippingUnit = filter(value => (value as any).LOV_TYPE == "SHIPPING_UNIT");

假设在解析对JSON的响应主体之后,你得到一个类型为Foo的数组,其中Foo的定义如下:

interface Foo {
 LOV_TYPE: string;
 fooProperty: string;
 fooNumber: number;
}

您正在尝试将过滤器应用于数组对象,而不是应用于其中包含的对象。

您有两个选择:展平数组并将其值作为单个事件发出,然后将它们再次作为数组放在一起,或将数组映射到新数组;第二个是最简单的如下:

const filterShippingUnit = map((list: Foo[])=> list
              .filter(foo => foo.LOV_TYPE === "SHIPPING_UNIT"));

第一种方法可以实现为:

import { flatMap, toArray } from 'rxjs/operators';

return this.http.get(this.constantsService.LOOKUP_COLUMN_BATCH_URL)
    .pipe(
      flatMap(response => response.json() as Foo[])
      map(foo => foo.LOV_TYPE === "SHIPPING_UNIT") // TypeScript will infer that foo is of type Foo
      toArray
     );

由于很容易注意到你刚开始有角度,我建议你:

  • 定义来自后端的所有内容的接口
  • 从角度使用新的HttpClient API(Http已弃用,请参阅https://angular.io/guide/http
  • 我认为没有必要定义常量函数来存储您将在流中使用的操作(如您所遵循的教程/指南中所建议的那样)。如果您没有明确声明参数类型,那么通过这样做会丢失所有类型信息。但是不要相信我这个,有些人说尽管打字稿可以推断出一个类型,但是明确地声明它是一个很好的做法......
© www.soinside.com 2019 - 2024. All rights reserved.