javascript - 调用 Web API - 无法读取未定义的属性 'filter'

标签 javascript angular typescript angular8

我试图避免 NULL 并将 API 响应中的唯一值显示到下拉列表中。我正在尝试以下内容

 export class ReportingFilterComponent implements OnInit {

 ShipmentList: ShipmentByProject[];
 shipTo= [];

 entityUrl = 'ShipmentDetail/GetByReportingProject?repPrj=000634';

 constructor(service: DataService) {

 service.get<ShipmentByProject[]>(this.entityUrl).subscribe(x => {this.ShipmentList = x });

 this.shipTo = this.ShipmentList.filter(_ => _.customer_shipto_name);
 const uniqueShipTo = new Set(this.shipTo);

并在 html 中使用 uniqueShipTo ,例如

<div class="dx-fieldset">
    <div class="dx-field">
        <div class="dx-field-label">ShipTo Account</div>
        <div class="dx-field-value">
            <dx-select-box [dataSource]="uniqueShipTo" ></dx-select-box>
        </div>
        </div>

但我收到错误

4200/vendor.js:43416 错误错误:未捕获( promise 中):TypeError:无法读取未定义的属性“过滤器” 类型错误:无法读取未定义的属性“过滤器”

API 调用有效,我收到了响应,但不知道为什么它说 未定义

最佳答案

我们面临的挑战是 HTTP 调用的异步特性。 您的代码目前执行以下操作:

  • 您使用 undefined 初始化 shipTo(通过不定义值来隐式初始化)
  • 您发出 HTTP 请求并注册回调函数,该函数应在响应返回时调用。
  • 您尝试访问 shipTo 上的 filter() 方法,该方法仍然未定义
  • HTTP 响应异步返回,订阅回调将被执行 - 但为时已晚。

为了避免这种情况,您需要在数据存在时触发转换逻辑(底部的内容),而不是更早。 最简单的方法是将其也放入订阅回调中。 然而,借助 RxJS 的强大功能,您可以更优雅地解决这个问题:

service.get<ShipmentByProject[]>(this.entityUrl).pipe(
  filter(_ => _.customer_shipto_name),
  map(filteredList => new Set(filteredList))
).subscribe(uniqueShipTo => {
  // you now have uniqueShipTo available and can work with it
});

现在您有了一个 Observable,它执行 HTTP 请求并发出唯一条目集。 为了将其引入模板,有两种方法。 第一个想法是将数据写入组件属性并从模板访问它。这几乎就是您已经做过的方式。

第二个想法更加优雅,避免了组件中的 subscribe() 。 我们省略 subscribe() 并将整个 Observable 放入组件属性中:

import { filter, map } from 'rxjs/operators';

// ...
uniqueShipTo$: Observable<Set<ShipmentByProject>>;

// ...
this.uniqueShipTo$ = service.get<ShipmentByProject[]>(this.entityUrl).pipe(
  filter(_ => _.customer_shipto_name),
  map(filteredList => new Set(filteredList))
);

然后在模板中你可以使用Angular的AsyncPipe来订阅这个Observable:

<div class="dx-fieldset">
    <div class="dx-field">
        <div class="dx-field-label">ShipTo Account</div>
        <div class="dx-field-value">
            <dx-select-box *ngIf="uniqueShipTo$ | async as shipTo" [dataSource]="shipTo" ></dx-select-box>
        </div>
        </div>

这里的关键是ngIf,它会删除选择框,直到没有可用数据为止。

关于javascript - 调用 Web API - 无法读取未定义的属性 'filter',我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57560642/

相关文章:

javascript - 在javascript中使用正则表达式获取整数

javascript - 尝试在 Chrome 中使用 jQuery 同步 AJAX + .ready() 时出现不可预测的行为

javascript - 如何让 Socket 只发送给发出请求的客户端?

javascript - Angular 2 router.navigate

visual-studio - Visual Studio 2017 - 防止 asmx 文件出现 typescript 错误

javascript - NodeJs 简单上传文件不返回正确的结果

angular - 选项卡选定索引内的垫选项卡不起作用

Angular 自定义 ngIf 指令 'as' 语法

typescript - 如何处理 typescript 中的不同类型?

javascript - typescript 如何编译类和普通匿名函数之间的实际区别是什么?