我试图避免 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/