Angular 2已填充输入字段仍出现Cannot read property of undefined错误
解决Angular中"Cannot read property of undefined"的问题
嘿,这个问题我太熟了!咱们先搞清楚为啥会出现这个错误:
你的getUserClaims()是一个异步HTTP请求——组件初始化时,userClaims一开始是undefined,但Angular会在数据从API返回之前就渲染模板。这时候如果模板里直接访问userClaims的属性(比如userClaims.username),就会触发"Cannot read property of undefined"的错误,因为这时候userClaims还没拿到数据呢!
下面给你几个靠谱的解决方案,按需选就行:
方案1:使用安全导航操作符(?.)
这是最简单的处理方式,在模板里访问属性时加上?.,它会自动判断userClaims是否存在,只有当它有值的时候才会访问后面的属性:
<div class="col s12 m8 l9"> <ul class="collapsible collapsible-accordion" data-collapsible="accordion"> <!-- 举个例子,访问email属性 --> <li>{{ userClaims?.email }}</li> <input type="text" [value]="userClaims?.username"> </ul> </div>
方案2:用*ngIf先判断数据是否加载完成
把需要用到userClaims的DOM元素用*ngIf="userClaims"包裹,这样只有当数据返回后,这块内容才会被渲染,从根源避免错误:
<div class="col s12 m8 l9" *ngIf="userClaims"> <ul class="collapsible collapsible-accordion" data-collapsible="accordion"> <li>{{ userClaims.email }}</li> <input type="text" [value]="userClaims.username"> </ul> </div>
如果想在加载时显示提示,还可以加个else块:
<div class="col s12 m8 l9" *ngIf="userClaims; else loading"> <!-- 正常渲染内容 --> </div> <ng-template #loading> <p>加载中...</p> </ng-template>
方案3:初始化userClaims为空对象
在组件里把userClaims初始化为空对象,这样模板访问属性时不会因为undefined报错,只是暂时显示空,等数据返回后会自动更新:
// home.component.ts userClaims: any = {}; // 这里改成空对象 ngOnInit() { this.userService.getUserClaims().subscribe((data: any) => { this.userClaims = data; }); }
方案4:使用AsyncPipe(推荐!)
这个方式不用手动订阅Observable,Angular会帮你处理订阅和销毁,还能避免内存泄漏:
首先修改组件代码:
// home.component.ts import { Observable } from 'rxjs'; userClaims$: Observable<any>; // 改成Observable类型 ngOnInit() { this.userClaims$ = this.userService.getUserClaims(); // 直接赋值Observable }
然后模板里用async管道订阅,并把数据赋值给局部变量:
<div class="col s12 m8 l9" *ngIf="userClaims$ | async as userClaims"> <ul class="collapsible collapsible-accordion" data-collapsible="accordion"> <li>{{ userClaims.email }}</li> <input type="text" [value]="userClaims.username"> </ul> </div>
内容的提问来源于stack exchange,提问作者stack questions
相关产品推荐
相关产品推荐

