Angular 2 HttpClient获取REST数据失败问题求助
首先看你遇到的第一个核心错误:ERROR TypeError: Cannot read property 'product' of undefined,根源非常明确——你的productsService.find_p()方法返回的是Observable对象,而非直接的产品数据。你直接把这个Observable赋值给了product变量,所以在模板里访问item.product.product时,item.product是未解析的Observable实例,不是实际的产品对象,自然找不到product属性。
第一步:修正批量获取产品数据的逻辑
因为你需要为购物车里的每个item获取对应的产品信息,最适合的方式是用forkJoin来并行发起所有产品请求,等所有请求都完成后再合并数据到购物车items中。
修改你的basket.component.ts里的代码:
import { forkJoin } from 'rxjs'; // ... 其他已有代码 this.cartSubscription = this.cart.subscribe((cart) => { this.itemCount = cart.items .map((x) => x.quantity) .reduce((p, n) => p + n, 0); // 为每个购物车item创建对应的产品请求Observable const productObservables = cart.items.map(item => this.productsService.find_p(item.productId) ); // 用forkJoin等待所有请求完成,统一处理返回的产品数据 forkJoin(productObservables).subscribe((products) => { // 将产品数据与购物车item合并 this.cartItems = cart.items.map((item, index) => ({ ...item, product: products[index] })); }); });
第二步:优化find_p方法的类型与解析逻辑
Angular的HttpClient会自动解析JSON响应,不需要手动调用res.json(),同时可以通过泛型定义让返回类型更清晰,避免后续类型错误:
// 先根据你的接口返回结构定义产品类型(示例结构,按需调整) interface ProductResponse { product: { name: string; // 其他产品属性 }; // 接口返回的其他字段 } find_p(id: number | string): Observable<ProductResponse> { const url = `${this.BASE_URL}/product/${id}.json`; return this.http.get<ProductResponse>(url, { headers: this.headers }) .catch((error: any) => Observable.throw(error.error || 'Server error')); }
第三步:解决Property results does not exist on type Promise or observable错误
你提到的这个错误,大概率是尝试访问了Observable不存在的results属性。Observable本身没有这个属性,获取数据的正确方式是通过subscribe回调(像我们第一步里的写法),或者在单个Observable场景下用模板的async管道。
比如如果是单个产品的场景,模板可以这样写:
<a class="uk-link-reset" *ngIf='item.product$ | async as product' href="">{{ product.product.name }}</a>
但在我们的批量处理逻辑里,已经通过forkJoin把实际数据赋值给了cartItems,所以模板里直接访问item.product.product.name即可,不需要额外的async管道。
额外注意事项
- 记得在组件销毁时取消订阅,避免内存泄漏:
ngOnDestroy() { this.cartSubscription?.unsubscribe(); }
- 可以在模板里添加加载状态提示,提升用户体验:
<tbody *ngIf='cartItems; else loading'> <!-- 你的表格内容 --> </tbody> <ng-template #loading> <tr> <td colspan="6" class="uk-text-center">加载中...</td> </tr> </ng-template>
内容的提问来源于stack exchange,提问作者mohammad mahmoodi

