angular - Rxjs 管道不适用于 Angular 的 Http.get()

标签 angular typescript rxjs angular2-http rxjs-lettable-operators

我有一个调用服务获取数据的 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';

调试时,代码永远不会出错,只是永远不会到达组件中的 console.log() 语句。如果我删除 .pipe() 并简单地返回 Observable,代码将记录我期望的结果,而无需转换和过滤。

我对 Rxjs 和使用 Pipe 还很陌生。我显然不明白什么。

编辑以添加信息:

我像这样把水龙头放进管道里...

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

我不知道 tap 存在,但它很有用。前两个控制台日志给了我我所期望的。第三个,紧跟在 filterShippingUnit 之后,什么都不做。它根本不记录值。甚至不为空。

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

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

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

最佳答案

问题最有可能在这里:

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
     );

由于很容易注意到您只是从 Angular 开始,所以我建议您执行以下操作:

  • 为来自后端的一切定义接口(interface)
  • 从 Angular 使用新的 HttpClient API(Http 已弃用,请参阅 https://angular.io/guide/http)
  • 我认为没有必要定义常量函数来存储您将在流中使用的操作(如您所遵循的教程/指南中所建议的那样)。如果您不显式声明参数类型,那么这样做会丢失所有类型信息。但是在这一点上不要相信我,有些人说尽管 typescript 可以推断类型,但显式声明它是一种很好的做法......

关于angular - Rxjs 管道不适用于 Angular 的 Http.get(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47889865/

相关文章:

angular - 在 Guard.CanActivate 方法中调用 router.navigate 是否正确?

angular - 使用 webpack 从包中排除 ts/js 文件

javascript - Angular2,如何防止HTTP重定向

typescript - 将类型断言与解构赋值结合使用的最佳方式是什么?

node.js - 如何在 typescript 中导入 recursive-readdir

angular - 按对象属性过滤可观察数组

angular - 为什么使用 RxJS .asObservable() getter/factory 函数模式?

Angular svg不同实例共享相同的defs

angular - 在模型类 Angular 中注入(inject)服务

angular - 空注入(inject)器错误 : No provider for _CoalescedStyleScheduler