开发者问题收集

在从控制器接收数据之前,如何处理 Angular 应用程序中 html 中未定义的属性?

2021-12-02
2667

当我的 Angular 组件 HTML 呈现时。我会收到很多类似这样的错误

ERROR TypeError: Cannot read properties of undefined (reading 'someProperty')

在我的 HTML 页面中,我有很多类似这样的绑定

<h1>{{event.title.toUpperCase()}}</h1>

在大多数组件中,我调用服务从“ngOnInit()”中的控制器获取数据,并且我知道在数据从控制器返回之前防止此错误的一种解决方案是使属性可空,如下所示

event?.title

但这似乎不是一个实用的解决方案,特别是如果页面上有几十个。

我尝试过的 -

  1. 使用“?”使它们可空但这似乎不正确,特别是如果我总是这样做的话
  2. 将从控制器返回的对象类型设置为“任何”(例如事件:任何),但在某些情况下它仍然显示错误

问题 - 处理此问题的最佳解决方案是什么,以便在我的页面数据加载之前我不会继续收到这些错误?

我是否应该有一些条件,如 *ngIf="event" 并隐藏页面直到收到数据并在等待时显示一些加载指示器?或者有什么方法可以防止这些错误显示在控制台中?

编辑 - 这是我用来从控制器获取数据并将其设置为“事件”的代码

// component
event: any;

// ngOnInit()
this.eventService.getEvent(this.id).pipe(take(1)).subscribe(response => {
  this.event = response;
}, error => {
  console.log(error);
});

// service
getEvent(id: number): Observable <any> {
  return this.http.get<any>(this.baseUrl + 'events/' + id);
}
2个回答

定义一个布尔变量并检查数据是否已加载是最好的方法:

// component
event: any;
loaded: boolean;


// ngOnInit()
this.eventService.getEvent(this.id).pipe(take(1)).subscribe(response => {
  this.event = response;
  this.loaded = true;
}, error => {
  console.log(error);
});

在您的 HTML 页面中,将您的 HTML 标签放在一个部分或一个 div 标签内,如下所示:

<section *ngIf="loaded">

// your HTML tags here

</section>

这样您就不会一直收到未定义的错误,并且只有在数据真正加载时才会发生绑定。就是这样!

Omid Karami
2022-01-25

我会将受影响的 html 包装成类似这样的内容

<ng-container *ngIf="event">
...
</ng-container>

阅读您的描述时,我还建议使用可观察对象,即您的 http 调用作为模板中的异步绑定,而不是将其映射到具体对象“事件”。

为了向您提供更多信息,您需要提供更多代码。 [编辑] 您的 JS:

// class member
event$: Observable<any> = of(undefined);

// whereever
this.event$ = this.eventService.getEvent(this.id).pipe(take(1),
  catchError(error => {
    console.log(error);
    //or return something else
    return throwError(error);
  }));

HTML 中的绑定:

<ng-container *ngIf="(event$ | async) as event">
...
</ng-container>

[/编辑]

Malte
2021-12-02