Angular结合Firebase时GET请求数据无法渲染到DOM该如何解决
错误根因
Angular的*ngFor指令仅支持遍历数组等可迭代类型,你遇到的报错是因为Firebase实时数据库REST接口返回的用户数据是键值对结构的对象(键是每条记录的唯一ID,值是用户业务数据),不是数组结构,无法直接用于*ngFor遍历。
排查步骤
首先可以在getAllUsers的subscribe回调中打印返回结果,确认返回结构:
getAllUsers() { this.http.getUsers().subscribe((res) => { console.log('接口返回数据:', res); // 确认输出是否为对象结构 this.newUser = res; }); }
如果控制台输出的是{ "-Nxxxxxx": { "user": "xxx", "mail": "xxx" }, ... }这类对象结构,就可以按照以下方案修复。
修复方案
- 修改
http.service.ts中的接口处理逻辑,将返回的对象转为数组:
//GET users getUsers() { return this.http .get( 'https://n22-f7ae3-default-rtdb.europe-west1.firebasedatabase.app/users.json' ) .pipe( map((res: any) => { // 处理无数据的场景,返回空数组避免报错 if (!res) return []; // 遍历对象的键值对,转为数组,同时把Firebase生成的记录ID存入id字段 return Object.entries(res).map(([key, value]) => ({ id: key, ...value })); }) ); }
- 修改
home.component.ts中newUser的定义,明确为数组类型且初始化为空数组,避免初始渲染时遍历undefined:
// 初始化为空数组 newUser: any[] = []; //I have called it in 'ngOnInit' too. getAllUsers() { this.http.getUsers().subscribe((res) => { this.newUser = res; }); }
- (可选)优化模板,增加空状态兼容:
<tbody> <ng-container *ngIf="newUser.length; else emptyUser"> <tr *ngFor="let list of newUser"> <th scope="row">{{ list.id }}</th> <td>{{ list.user }}</td> <td>{{ list.mail }}</td> </tr> </ng-container> <ng-template #emptyUser> <tr> <td colspan="3">暂无用户数据</td> </tr> </ng-template> </tbody>
注意事项
如果你的用户业务数据中已经存在id字段,可将转换数组时的id: key改为firebaseId: key避免字段覆盖。
内容的提问来源于stack exchange,提问作者Ismail Beg
相关产品推荐
相关产品推荐

