Angular9:NgFor迭代报错及HttpClient请求后端数据未显示日志
我来帮你搞定这两个Angular常见问题,都是异步处理和数据结构不匹配导致的,咱们一步步来解决:
问题1:NgFor报错 "Cannot find a differ supporting object '[object Object]'"
原因分析
你后端返回的JSON结构是一个包含response数组的对象,而不是直接的员工数组:
{"response": [你的员工数组]}
但你的RestAPIServices里声明getEmployee()返回的是Observable<Employee[]>,组件里直接把返回的整个对象赋值给了listEmployee,而NgFor只能遍历数组这类可迭代对象,所以就会报错。
解决办法
你有两种选择来修正这个数据结构不匹配的问题:
方案A:修改Service,直接返回员工数组
先导入RxJS的map操作符,然后在请求后提取response属性:
// 在service.ts顶部添加 import { map } from 'rxjs/operators'; // 修改getEmployee方法 getEmployee(): Observable<Employee[]> { return this.httpClient.get<{response: Employee[]}>("http://127.0.0.1/angularCRUDservices/user/getEmployees") .pipe( map(res => res.response) // 提取response里的员工数组 ); }
这样组件里直接赋值this.listEmployee = data就没问题了。
方案B:在组件的回调里提取数组
如果不想改动Service,就在subscribe的回调中手动取出response数组:
// app.component.ts的ngOnInit里 this._employeeService.getEmployee().subscribe( data=>{ console.log(data); // 这里会打印整个后端返回的对象 this.listEmployee = data.response; // 取出response里的数组 } );
问题2:请求数据未显示在日志中
原因分析
你把console.log(this.listEmployee)写在了subscribe回调的外面,而HTTP请求是异步操作,这行代码会在请求还没返回数据的时候就执行,此时listEmployee还是初始的undefined,所以看起来像是没拿到数据,但实际上请求是正常的。
解决办法
把日志打印代码移到subscribe的回调函数内部,确保只有当数据返回后才执行:
ngOnInit(){ this._employeeService.getEmployee().subscribe( data=>{ console.log(data); // 打印后端返回的原始数据 this.listEmployee = data.response; // 或者如果用了方案A就写this.listEmployee = data console.log(this.listEmployee); // 这里就能打印到正确的员工数组了 } ); // 原来这里的console.log会先执行,此时数据还没返回,所以不要放在这里 }
额外提示:类型匹配优化
后端返回的id是字符串类型(比如"1"),isActive是字符串"1",但你的Employee模型里这两个字段分别是number和boolean,如果需要严格类型匹配,可以在提取数组的时候做类型转换:
// 在Service的map里添加转换逻辑 map(res => res.response.map(emp => ({ ...emp, id: Number(emp.id), isActive: emp.isActive === '1' })))
这样修改后,你的应用应该就能正常渲染员工列表,并且日志也能正确显示数据了!
内容的提问来源于stack exchange,提问作者user2510946

