Angular 角度6+;TypeError:无法读取属性';名字';未定义的
我的(角度6.1.2)视图在我的可观察对象加载之前加载,因此产生了未定义的错误。控制台错误后,数据正确地结束在那里 组成部分Angular 角度6+;TypeError:无法读取属性';名字';未定义的,angular,typescript,observable,Angular,Typescript,Observable,我的(角度6.1.2)视图在我的可观察对象加载之前加载,因此产生了未定义的错误。控制台错误后,数据正确地结束在那里 组成部分 ngOnInit() { this.route.params.subscribe(params => { this.UserId = params['id']; this.objectService.get(this.UserId).subscribe((ret: user) => { this.
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}`);
}
public get(id:string):可观察{
返回this.http.get(`${this.api}/${id}`);
}
HTML
{{User.firstName}}
首先检查它会抑制错误
{{User.firstName}}
但我想知道如何从控制器和/或服务正确执行此操作,以便我的视图在不检查数据的情况下工作。
使用内存中的api btw
2019年更新:
我已经切换到使用路由器解析数据,这样我就可以在模板中使用异步管道轻松处理这个问题。这种方法使我省去了许多麻烦
更新:
看来大家一致认为我们不应该在视图中进行检查。在使用变量之前正确设置变量似乎是最好的方法。我选择在如下设置变量时利用导出的类:
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();
}
public user:user=new user()停止未定义错误的代码>。处理此错误的一种方法是使用空名字初始化组件中的用户处理此错误的一种方法是使用空名字初始化组件中的用户解决此问题的方法有三种:
1-在与?
绑定之前检查变量,如{{User?.firstName}
2-使用空对象启动变量User={}
3-使用空用户实例启动变量
class User {
name: string;
...
}
class UserGrid {
user: User = new User();
}
正如错误所述,无法读取未定义的属性
提示:不要使用第一个大写字母作为变量名。这适用于类和类型,如user:user=newuser()代码>解决此问题有三种方法:
1-在与?
绑定之前检查变量,如{{User?.firstName}
2-使用空对象启动变量User={}
3-使用空用户实例启动变量
class User {
name: string;
...
}
class UserGrid {
user: User = new User();
}
正如错误所述,无法读取未定义的属性
提示:不要使用第一个大写字母作为变量名。这适用于类和类型,如user:user=newuser()代码>首先,你现在的做法是正确的。另一个更好的方法是@vinagreti建议的解决方案1
这是因为当您的组件初始化时,模板被加载,但是您的用户
对象是未定义的
,因为This.User=User代码>位于异步rxjs调用中
这就是为什么在模板{{User.firstName}}
中返回错误的原因,因为您正在从undefined读取firstName
@vinagreti提出的解决方案已经是最好的解决方案。就我个人而言,我更喜欢在大多数情况下使用{{User?.firstName}
。首先,你现在的做法是正确的。另一个更好的方法是@vinagreti建议的解决方案1
这是因为当您的组件初始化时,模板被加载,但是您的用户
对象是未定义的
,因为This.User=User代码>位于异步rxjs调用中
这就是为什么在模板{{User.firstName}}
中返回错误的原因,因为您正在从undefined读取firstName
@vinagreti提出的解决方案已经是最好的解决方案。就我个人而言,我更喜欢在大多数情况下使用{{User?.firstName}
。Rxjs switchmap是在另一个订阅中订阅的优雅方式
User={}
ngOnInit() {
this.route.params.switchMap(params=>{
this.objectService.get(params['id'])
}).subscribe((ret: user) => {
this.User = ret;
});
});
}
Rxjs switchmap是在另一个subscribe中订阅的优雅方式
User={}
ngOnInit() {
this.route.params.switchMap(params=>{
this.objectService.get(params['id'])
}).subscribe((ret: user) => {
this.User = ret;
});
});
}
您是对的,理想情况下,我们不应该将检查逻辑放在视图中。您可以这样做:
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();
}
在您的组件中:
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;
}
});
});
}
<h1>{{firstName}}</h1>
然后在您的视图中html:
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;
}
});
});
}
<h1>{{firstName}}</h1>
您是对的,理想情况下,我们不应该将检查逻辑放在视图中。您可以这样做:
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();
}
在您的组件中:
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;
}
});
});
}
<h1>{{firstName}}</h1>
然后在您的视图中html:
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;
}
});
});
}
<h1>{{firstName}}</h1>
您可以使用{User?.firstName}
然后不需要ngIf
,但这只是用另一种方式检查数据。您可以使用{User?.firstName}
然后不需要ngIf
,但这只是用另一种方式检查数据。在init上向整个用户对象添加空白值?嗯,也许是最便宜的选择,但也许我做错了什么?这似乎是我以前从未遇到过的新问题。在init上向整个用户对象添加空白值?嗯,也许是最便宜的选择,但也许我做错了什么?这似乎是一个我从未遇到过的新问题。谢谢你的回答。两件事:为什么我们不在视图中检查?我喜欢您为每个预期数据段分配变量的想法。这可能是我在控制器端看到的最好的检查方法。理想情况下,我们应该在视图中放置尽可能少的逻辑,视图应该只用于显示数据。在视图中放置逻辑将降低应用程序的性能。当你的观点没有那么多逻辑时,这可能并不明显,但作为一种最佳实践,你不应该这样做。谢谢你的回答。两件事:为什么我们不在视图中检查?我喜欢您为每个预期数据段分配变量的想法。这可能是我在控制器端看到的最好的检查方法。理想情况下,我们应该在视图中放置尽可能少的逻辑,视图应该只用于显示数据。在视图中放置逻辑将降低应用程序的性能。当你的观点中没有那么多逻辑时,这可能并不明显,但作为一种最佳实践,你不应该这样做。