Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Angular 角度6+;TypeError:无法读取属性';名字';未定义的_Angular_Typescript_Observable - Fatal编程技术网

Angular 角度6+;TypeError:无法读取属性';名字';未定义的

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.

我的(角度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}`);
}
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上向整个用户对象添加空白值?嗯,也许是最便宜的选择,但也许我做错了什么?这似乎是一个我从未遇到过的新问题。谢谢你的回答。两件事:为什么我们不在视图中检查?我喜欢您为每个预期数据段分配变量的想法。这可能是我在控制器端看到的最好的检查方法。理想情况下,我们应该在视图中放置尽可能少的逻辑,视图应该只用于显示数据。在视图中放置逻辑将降低应用程序的性能。当你的观点没有那么多逻辑时,这可能并不明显,但作为一种最佳实践,你不应该这样做。谢谢你的回答。两件事:为什么我们不在视图中检查?我喜欢您为每个预期数据段分配变量的想法。这可能是我在控制器端看到的最好的检查方法。理想情况下,我们应该在视图中放置尽可能少的逻辑,视图应该只用于显示数据。在视图中放置逻辑将降低应用程序的性能。当你的观点中没有那么多逻辑时,这可能并不明显,但作为一种最佳实践,你不应该这样做。