Angular 5从API获取数据时NgFor报错的解决方法
解决Angular中NgFor绑定非可迭代对象的错误
嘿,我一眼就看出你的问题所在了——那个Cannot find a differ supporting object '[object Object]'错误的核心原因是:*ngFor只能遍历数组这类可迭代集合,但你的API返回的是一个对象,不是直接的数组,所以Angular不知道该怎么循环它。
咱们一步步来搞定这个问题:
第一步:先搞清楚API返回的数据结构
你可以先在组件的subscribe里加个控制台打印,看看接口到底返回了什么内容:
showProducts() { this.data.showProducts() .subscribe(res => { console.log('API返回的数据:', res); // 打开浏览器控制台查看输出 this.products = res; }); }
通常后端API不会直接返回数组,而是会把数组包在一个对象里,比如{ data: [产品列表] }或者{ products: [产品列表] }这种格式。
第二步:提取对象中的数组部分
如果控制台显示返回的是类似{ data: [...] }的结构,那你只需要把里面的数组提取出来赋值给products就行:
showProducts() { this.data.showProducts() .subscribe(res => { // 提取res里的data数组赋值给products this.products = res.data; }); }
要是你不确定数组对应的字段名,也可以做个兜底处理,确保products永远是数组:
showProducts() { this.data.showProducts() .subscribe(res => { // 先判断res本身是不是数组,不是的话就尝试找可能的数组字段,兜底为空数组 this.products = Array.isArray(res) ? res : (res?.products || res?.data || []); }); }
第三步:避免初始值导致的报错
你的products变量一开始是undefined,Angular初始化时会因为找不到可迭代对象报错,所以最好在组件里给它初始化为空数组:
export class ProductsComponent implements OnInit { products: any[] = []; // 初始化为空数组 // ... 其他代码不变 }
第四步:修复HTML模板的结构问题
你现在的HTML里{{product.product_name}}没有放在<td>标签里,这样会把内容直接放在<tr>里,破坏表格结构,记得把每个字段放在对应的单元格中:
<div> <table border="1"> <tr> <th>Product</th> <th>Code</th> <th>Price</th> <th>Action</th> </tr> <!-- 每个字段都放在<td>标签内 --> <tr *ngFor="let product of products"> <td>{{product.product_name}}</td> <td>{{product.product_code}}</td> <!-- 假设你的产品有code字段 --> <td>{{product.price}}</td> <td><button>Edit</button></td> </tr> </table> </div>
进阶推荐:用Async管道(更优雅)
如果想避免手动订阅和取消订阅(防止内存泄漏),可以把products改成Observable,用async管道来处理:
组件代码:
import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; // ... export class ProductsComponent implements OnInit { products$: Observable<any[]>; // 用$后缀标记这是Observable类型 constructor(private data: DataService) { } ngOnInit() { this.products$ = this.data.showProducts().pipe( map(res => Array.isArray(res) ? res : (res?.products || res?.data || [])) ); } }
HTML模板:
<div> <table border="1"> <tr> <th>Product</th> <th>Code</th> <th>Price</th> <th>Action</th> </tr> <!-- 用async管道自动处理订阅和取消订阅 --> <tr *ngFor="let product of products$ | async"> <td>{{product.product_name}}</td> <td>{{product.product_code}}</td> <td>{{product.price}}</td> <td><button>Edit</button></td> </tr> </table> </div>
这样一套操作下来,你的错误应该就能彻底解决啦~
内容的提问来源于stack exchange,提问作者Adel Rayan
相关产品推荐
相关产品推荐

