Angularfire+Ionic4如何将Firebase对象数据从服务正确传递到页面
你遇到的报错本质是模板渲染时机早于异步请求返回时机,和Promise传递对象的逻辑无关:
组件初始化时模板会立刻渲染,此时你在constructor里触发的Firebase异步请求还没完成,localData 还处于未赋值的undefined状态,直接访问localData.id自然会抛出Cannot read properties of undefined (reading 'id')错误。
修复方案
方案1:使用可选链运算符(最简修复)
直接修改mypage.page.html里的取值逻辑,加?.可选链运算符,当localData为undefined/null时会直接返回undefined,不会抛出错误,等异步数据返回后会自动更新渲染:
<ion-content> <ion-label>{{ localData?.id }}</ion-label> </ion-content>
方案2:使用*ngIf控制渲染逻辑(体验更好)
可以加加载状态提示,同时避免空值报错:
<ion-content> <ng-container *ngIf="localData; else loading"> <ion-label>{{ localData.id }}</ion-label> </ng-container> <ng-template #loading> <ion-label>数据加载中...</ion-label> </ng-template> </ion-content>
额外优化建议
- 异步请求建议放到
ngOnInit生命周期钩子中执行,constructor仅用来做依赖注入,符合Angular开发规范:
修改mypage.page.ts代码:
export class MypagePage implements OnInit { localData: DataObject; constructor(private firebaseService: FirebaseService) {} ngOnInit() { this.firebaseService.getData().then(data => { this.localData = data; }).catch((error) => { console.error(error); }); } }
- 优化Service返回值类型,避免any,提升类型安全:
修改firebase.service.ts中getData方法的返回值声明:
getData(): Promise<DataObject | null> { return this.databaseRef.child('data').get().then((snapshot) => { if (snapshot.exists()) { return {id: '1', data: snapshot.val()}; } else { return null; } }).catch((error) => { console.error(error); throw error; // 抛出错误让上层catch处理 }); }
内容的提问来源于stack exchange,提问作者Jakub Szlaur
相关产品推荐
相关产品推荐

