Angular 角度7:数据显示在页面上,但控制台具有“无法读取”属性

Angular 角度7:数据显示在页面上,但控制台具有“无法读取”属性,angular,promise,observable,angular7,Angular,Promise,Observable,Angular7,我正在使用我正在构建的Angular 7应用程序,在从API返回数据并正确地将其写入页面时遇到了一些问题 我试图遵循承诺和可观察性的指导,但我似乎既不能使数据正确地显示在标题中,也不能使控制台停止抛出错误。我尝试使用运算符,但这只会使显示值为空,而不是显示值 resume.service.ts export class ResumeService { nameURL: string = 'REDACTED'; constructor(private http: HttpClient)

我正在使用我正在构建的Angular 7应用程序,在从API返回数据并正确地将其写入页面时遇到了一些问题

我试图遵循承诺和可观察性的指导,但我似乎既不能使数据正确地显示在标题中,也不能使控制台停止抛出错误。我尝试使用运算符,但这只会使显示值为空,而不是显示值

resume.service.ts

export class ResumeService {
  nameURL: string = 'REDACTED';

  constructor(private http: HttpClient) { }

  getName() {
    return this.http.get(this.nameURL);
  }
}
返回this.http.get(this.nameURL)

navbar.component.ts

export class NavbarComponent implements OnInit {
  data: Name;
  reason = '';
  @ViewChild('sidenav') sidenav: MatSidenav;

  constructor(private http: HttpClient, private resumeAPI: ResumeService) {
    this.resumeAPI.getName().subscribe(res => {
      this.data = res[0];
    });
  }

  close(reason: string) {
    this.reason = reason;
    this.sidenav.close();
  }
}

export interface Name {
  name: string
}
navbar.component.html

<div>
  <a routerLink="/">
    {{ this.data.name }}
  </a>
</div>
<a routerLink="/" >
  {{ this.data?.name }}
</a>
import { Component, ViewChild, ChangeDetectorRef } from '@angular/core';
import { MatSidenav } from '@angular/material/sidenav';
import { HttpClient } from '@angular/common/http';
import { ResumeService } from '../services/resume.service';

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss'],
  providers: [ResumeService]
})
export class NavbarComponent {
  data: Name;
  reason = '';
  @ViewChild('sidenav') sidenav: MatSidenav;

  constructor(private ref: ChangeDetectorRef, private resumeAPI: ResumeService) {
    this.resumeAPI.getName().subscribe(res => {
      this.data = res[0];
      this.ref.detectChanges();
    });
  }

  close(reason: string) {
    this.reason = reason;
    this.sidenav.close();
  }
}

export interface Name {
  name: string
}

(它显示了模糊区域所在的我的名字-这是API返回的数据)

但是,在控制台中,我看到了以下内容 (该链接有控制台错误的图片,但具体如下: 无法读取未定义的属性“name”

我知道它是在API为渲染提供数据之前抛出错误,但我不确定如何避免,因为将HTML更改为{this.data?.name}会使导航栏变为空白,{{this.data.name?}会导致此错误:表达式意外结束:{{this.data.name?}

删除“this”在HTML文件中

{{ data.name }}
删除HTML文件中的“this”

{{ data.name }}

在您的例子中,
this.http.get()
执行异步操作。因此,在运行
this.data=res[0];
行之前,
this.data
尚未初始化,它会抛出一个错误

您只需检查
此.data
是否通过

<a routerLink="/" *ngIf="this.data">
    {{ this.data.name }}
</a>
和在模板中

<a routerLink="/">
   {{ (this.data | async).name }}
</a>

{{(this.data | async.name}}

在您的示例中,
this.http.get()
执行异步操作。因此,在运行
this.data=res[0];
行之前,
this.data
尚未初始化,它会引发错误

您只需检查
此.data
是否通过

<a routerLink="/" *ngIf="this.data">
    {{ this.data.name }}
</a>
和在模板中

<a routerLink="/">
   {{ (this.data | async).name }}
</a>

{{(this.data | async.name}}

此问题的解决方案是将角度型芯更改DetectorRef与detectChanges()一起使用。所有功劳归于@MullisS

在TypeScript文件中,我们更改了:
从'@angular/core'导入{Component,ViewChild};
从'@angular/core'导入{Component,ViewChild,ChangeDetectorRef};
(添加了ChangeDetectorRef)

在构造函数中,我们更改了:
constructor(private-resumeAPI:ResumeService){
to
constructor(private-ref:ChangeDetectorRef,private-resumeAPI:ResumeService){

在订阅功能中,我们更改了:

this.resumeAPI.getName().subscribe(res => {
  this.data = res[0];
});


以下是完整的代码解决方案供参考: navbar.component.html

<div>
  <a routerLink="/">
    {{ this.data.name }}
  </a>
</div>
<a routerLink="/" >
  {{ this.data?.name }}
</a>
import { Component, ViewChild, ChangeDetectorRef } from '@angular/core';
import { MatSidenav } from '@angular/material/sidenav';
import { HttpClient } from '@angular/common/http';
import { ResumeService } from '../services/resume.service';

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss'],
  providers: [ResumeService]
})
export class NavbarComponent {
  data: Name;
  reason = '';
  @ViewChild('sidenav') sidenav: MatSidenav;

  constructor(private ref: ChangeDetectorRef, private resumeAPI: ResumeService) {
    this.resumeAPI.getName().subscribe(res => {
      this.data = res[0];
      this.ref.detectChanges();
    });
  }

  close(reason: string) {
    this.reason = reason;
    this.sidenav.close();
  }
}

export interface Name {
  name: string
}

此问题的解决方案是将角度磁芯更改DetectorRef与detectChanges()一起使用。所有功劳都归@MullisS

在TypeScript文件中,我们更改了:
从'@angular/core'导入{Component,ViewChild};
从'@angular/core'导入{Component,ViewChild,ChangeDetectorRef};
(添加了ChangeDetectorRef)

在构造函数中,我们更改了:
constructor(private-resumeAPI:ResumeService){
to
constructor(private-ref:ChangeDetectorRef,private-resumeAPI:ResumeService){

在订阅功能中,我们更改了:

this.resumeAPI.getName().subscribe(res => {
  this.data = res[0];
});


以下是完整的代码解决方案供参考: navbar.component.html

<div>
  <a routerLink="/">
    {{ this.data.name }}
  </a>
</div>
<a routerLink="/" >
  {{ this.data?.name }}
</a>
import { Component, ViewChild, ChangeDetectorRef } from '@angular/core';
import { MatSidenav } from '@angular/material/sidenav';
import { HttpClient } from '@angular/common/http';
import { ResumeService } from '../services/resume.service';

@Component({
  selector: 'app-navbar',
  templateUrl: './navbar.component.html',
  styleUrls: ['./navbar.component.scss'],
  providers: [ResumeService]
})
export class NavbarComponent {
  data: Name;
  reason = '';
  @ViewChild('sidenav') sidenav: MatSidenav;

  constructor(private ref: ChangeDetectorRef, private resumeAPI: ResumeService) {
    this.resumeAPI.getName().subscribe(res => {
      this.data = res[0];
      this.ref.detectChanges();
    });
  }

  close(reason: string) {
    this.reason = reason;
    this.sidenav.close();
  }
}

export interface Name {
  name: string
}


只需使用
{{this.data?.name}
,在api调用成功之前,数据是未定义的,因此出现控制台错误。一旦定义了
数据
,模板将显示名称。阅读有关“safeNavigation”操作的内容,该
{this.data?.name}
将字段无限期保留为空,并且从不呈现新数据。。可以尝试在API中使用
{{this.data?.name}
并调用ChangeDetection-call@MullisS这就成功了!@MullisS我发布了解决方案并给了你荣誉!谢谢你使用
{{{this.data?.name}
,在api调用成功之前,数据是未定义的,因此出现控制台错误。一旦定义了
数据
,模板将显示名称。阅读关于“安全导航”的操作或已经经历过的操作,
{{this.data?.name}
将字段无限期保留为空,并且从不呈现新数据。。可以尝试使用
{{this.data?.name}
并在API中调用ChangeDetection-call@MullisS这就是诀窍!@MullisS我发布了解决方案并给了你们荣誉!谢谢你们,所以尝试了两种方法。第一种方法对ngif不起作用,因为它从不显示数据。它只是保持空白。和这个一样。数据?正如我前面所说的…-至于下半部分,我完全按照你们说的做了幸运的是,我在控制台中遇到了相同的错误。“无法读取null的属性‘name’”
console.log
?不,很抱歉,我没有在控制台上记录任何东西。当我实现
this.data=this.resumeAPI.getName().pipe(map(res=>res[0]);
在导航栏的构造函数中,以及
{(this.data | async).name}
在我的HTML中,将此.data分配给res[0]后,错误控制台使用“{this.data?.name}}”并结合使用此.ref.detectChanges()的@MullisS-answer,弹出“无法读取null的属性'name'按预期工作。所以尝试了两种方法。第一种方法不适用于ngif,因为它从不显示数据。它只是保持空白。和this.data相同?正如我前面所说的…-至于第二种方法,我完全按照您所说的做了,不幸的是,我在控制台中遇到了相同的错误。“无法读取null的属性‘name’。”你把
console.log
放在哪里?不,对不起,我不是console.log'ing任何东西。当我实现
this.data=this.resumeAPI.getName().pipe(map(res=>res[0]);
在我的导航栏构造函数中,以及
{(this.data | async.name}}
在我的HTML中,错误控制台会弹出“无法读取属性”