我的(Angular 6.1.2)视图在我的可观察对象之前加载,因此创建了未定义的错误。控制台错误后,数据正确地存储在那里。
组件
ngOnInit() {
this.route.params.subscribe(params => {
this.UserId = params['id'];
this.objectService.get(this.UserId).subscribe((ret: user) => {
this.User = user;
});
});
}
服务
public get(id: string): Observable<User> {
return this.http.get<User>(`${this.api}/${id}`);
}
HTML
<h1>{{User.firstName}}</h1>
首先检查它可以消除错误。
<h1 *ngIf="User">{{User.firstName}}</h1>
但是我想从控制器和/或服务中知道如何正确执行此操作,这样我的视图就可以工作而无需检查数据。 使用内存中的API btw。
UPDATE 2019: 我已经切换到使用路由器解析数据,然后可以通过模板中的异步管道轻松解决此问题。这种方法使我省去了很多麻烦。
更新: 看来我们不应该在视图中进行检查。最好在使用变量之前正确设置它们。像这样设置变量时,我选择利用导出的类:
public user: User = new User();
将停止未定义的错误。
答案 0 :(得分:2)
您可以通过三种方式解决此问题:
1-与?
之类的<h1>{{User?.firstName}}</h1>
绑定变量之前先进行检查
2-以empt对象User = {}
开头的变量;
3-使用empt用户实例启动变量
class User {
name: string;
...
}
class UserGrid {
user: User = new User();
}
错误显示cannot read property of undefined
提示:变量名不要使用首字母大写。这适用于user: User = new User();
答案 1 :(得分:2)
您是对的,理想情况下,我们不应该在视图中放入检查逻辑。您可以执行以下操作:
在您的组件中:
public firstName: string;
ngOnInit() {
this.route.params.subscribe(params => {
this.UserId = params['id'];
this.objectService.get(this.UserId).subscribe((ret: user) => {
if (user) {
this.firstName = user.firstName;
}
});
});
}
然后在您的视图中html:
<h1>{{firstName}}</h1>
此外,作为订阅和更好性能的最佳实践,您应该订阅ngOnInit,然后取消订阅ngOnDestroy,如下所示:
import { Subscription } from "rxjs";
public firstName: string;
private userSub: Subscription;
ngOnInit() {
this.route.params.subscribe(params => {
this.UserId = params['id'];
this.userSub = this.objectService.get(this.UserId).subscribe((ret: user) => {
if (user) {
this.firstName = user.firstName;
}
});
});
}
public ngOnDestroy() {
this.userSub.unsubscribe();
}
答案 2 :(得分:1)
首先,您现在的方法是正确的方法之一。另一个更好的方法是@vinagreti建议的解决方案1。
之所以发生这种情况,是因为在初始化组件时,模板已加载,但是CompletionItem
对象是User
,因为undefined
位于异步rxjs调用内。
这就是在模板this.User = user;
中返回错误的原因,因为您正在从未定义中读取{{User.firstName}}
。
@vinagreti提出的解决方案已经是最好的解决方案。就我个人而言,在大多数情况下,我更喜欢使用firstName
。
答案 3 :(得分:1)
Rxjs switchmap是在另一个订阅中进行订阅的优雅方式
User={}
ngOnInit() {
this.route.params.switchMap(params=>{
this.objectService.get(params['id'])
}).subscribe((ret: user) => {
this.User = ret;
});
});
}
答案 4 :(得分:0)
一种处理方法是用空的firstName初始化组件中的User