Javascript 调用Web API-无法读取未定义的属性“筛选器”

Javascript 调用Web API-无法读取未定义的属性“筛选器”,javascript,angular,typescript,angular8,Javascript,Angular,Typescript,Angular8,我试图避免NULL,并在下拉列表中显示API响应中的唯一值。我正在尝试下面的方法 export class ReportingFilterComponent implements OnInit { ShipmentList: ShipmentByProject[]; shipTo= []; entityUrl = 'ShipmentDetail/GetByReportingProject?repPrj=000634'; constructor(service: DataServi

我试图避免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错误:承诺中未捕获:TypeError:无法读取未定义的属性“filter” TypeError:无法读取未定义的属性“filter”


API调用起作用了,我得到了响应,但不确定为什么它说未定义。我们在这里遇到的挑战是HTTP调用的异步性质。 您的代码目前执行以下操作:

通过不定义值,可以隐式地使用未定义的值初始化shipTo 发送HTTP请求并注册回调函数,响应返回时应调用回调函数。 您尝试访问尚未定义的shipTo上的筛选器方法 HTTP响应以异步方式返回,订阅回调将被执行,但为时已晚。 为了避免这种情况,您需要在数据存在时触发转换逻辑,而不是更早。 最简单的方法是将它也放入subscribe回调中。 然而,借助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
});
然后在模板中,您可以使用Angular的AsyncPipe订阅此可观察对象:

付帐
这里的关键是ngIf,它将删除选择框,直到没有可用的数据。

感谢您提供详细的答案。但是我需要在不同的组件中使用响应数据,如果我在API调用中使用过滤器,除了customer_shipto_name之外,我不会得到任何其他东西??您可以将组件中的整个运营商链放入服务中。您的服务可以具有通用方法service.get和更专门的方法,该方法获取相同的内容,但将其转换为一组唯一的shipTo地址。如果您想缓存响应以便保存HTTP调用,shareReplay操作员是您的朋友。您能给我演示一下如何处理缓存结果以删除null并使其唯一吗?我用我的尝试更新了这个问题
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))
);