【问题标题】:Angular HTML Binding Error with JSON array from Express Subscribe call来自 Express 订阅调用的 JSON 数组的 Angular HTML 绑定错误
【发布时间】:2018-05-03 13:57:09
【问题描述】:

我目前的设置是这样的。

  1. ngOnInIt 为我的dashboard.component.ts 运行databaseService 调用以订阅结果。

  2. database.service.ts 运行 http POST 以获取数据并填充值 IssuerGroup

  3. 我想以 HTML 格式显示我的数据库给我的JSON 的结果。

代码如下:

dashboard.component.ts

import { IssuerGroup } from './../database.service';
import { Component, OnInit } from '@angular/core';
import { RouterLink } from '@angular/router';
import { FormArray, FormControl, FormGroup, Validators } from '@angular/forms';
import { Observable } from 'rxjs/Observable';
import { HttpClient } from '@angular/common/http';
import { element } from 'protractor';
import { ActivatedRoute } from '@angular/router';
import { DatabaseService } from '../database.service';

@Component({
  selector: 'app-dashboard',
  templateUrl: './dashboard.component.html',
  styleUrls: ['./dashboard.component.css']
})
export class DashboardComponent implements OnInit {

  issuerGroups: IssuerGroup[];

  constructor(
    private databaseService: DatabaseService,
    private route: ActivatedRoute
  ) {}

  ngOnInit() {
    const id = this.route.snapshot.paramMap.get('id');
    this.databaseService.getGroup(id)
      .subscribe(issuerGroups => this.issuerGroups = issuerGroups);
  }
}

database.service.ts

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { Observable } from 'rxjs/Observable';
import { map } from 'rxjs/operators';
import 'rxjs/add/operator/catch';
import 'rxjs/add/observable/throw';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/toPromise';

export class IssuerGroup {
  Issuer_Id: number;
  Issuer_Name: string;
  Issuer_Group_Name: string;
}
@Injectable()
export class TeradataService {
  constructor(private _http: HttpClient) {}

  getGroup(id): Observable<IssuerGroup[]> {
    const url = 'http://localhost:3000/ig';
    const data = ({
      issuerid: id
    });
    return this._http.post(url, data)
    .pipe(
      map((res) => {
        console.log(res);
        return <IssuerGroup[]> res;
      })
    );
  }
}

dashboard.component.html

<p> Display the Issuer Name here: {{ issuerGroups.Issuer_Name }} </p>

<!-- ERROR TypeError: Cannot read property 'Issuer_Name' of undefined -->

<p> Display the Issuer Name here: {{ issuerGroup.Issuer_Name }} </p>

<!-- ERROR TypeError: Cannot read property 'Issuer_Name' of undefined -->

<p> Display the Issuer Name here: {{ issuerGroups[0].Issuer_Name }} </p>

<!-- this last result produces the following error but the data actually displays on screen correctly -->

<!-- ERROR TypeError: Cannot read property '0' of undefined -->

在我在 HTML 页面中的最后一个示例中,数据显示但仍然收到错误。

目标:在我的 HTML 页面中显示我从数据库中返回的 JSON 的结果,并且没有错误。任何帮助将不胜感激。

【问题讨论】:

    标签: javascript html arrays json angular


    【解决方案1】:

    问题是您在模板中使用的属性可能还不存在。解释你的错误:

    <p> Display the Issuer Name here: {{ issuerGroups.Issuer_Name }} </p>
    

    这会失败,因为在加载数据之前,issuerGroups 变量不会初始化为任何对象值,并且您显然无法读取undefined 的属性。数据加载后它不会失败,但它也不会显示任何内容,因为issuerGroups 被设置为数组类型,它没有Issuer_Name 字段。

    <p> Display the Issuer Name here: {{ issuerGroup.Issuer_Name }} </p>
    

    这将始终失败,因为您根本没有在组件中定义 issuerGroup 字段。

    <p> Display the Issuer Name here: {{ issuerGroups[0].Issuer_Name }} </p>
    

    在加载数据之前这会失败,因为数组没有初始化,即使你已经用[] 初始化了它,它里面也没有任何元素,因此你不能读取 0 索引处的条目,直到那里存在一个.

    你应该做的是:

    <p> Display the Issuer Name here: {{ getIssuerName() }} </p>
    

    并在控制器中添加一个方法:

    getIssuerName() {
        if (this.issuerGroups && this.issuerGroups.length > 0) {
            return this.issuerGroups.Issuer_Name[0];
        } else {
            return "";
        }
    }
    

    (当然你可以在你的 HTML 文件中做内联检查,就像其他人建议的那样,该方法只是为了代码可读性)

    TL;DR:
    不要访问尚未加载的异步加载对象的成员。

    【讨论】:

      【解决方案2】:

      您可以在将变量绑定到 HTML 模板时使用 the safe navigation operator(在属性前使用 ?),例如:

      {{ issuerGroups?.Issuer_Name }}
      

      它对你的视图全局表示Issuer_Name 仅当 issuerGroups 存在(不是nullundefined)。优点是您不必使用*ngIf(某些情况除外)或进一步检查该属性是否存在以将其显示到您的视图中。

      所以在你的例子中它看起来像:

      <p> Display the Issuer Name here: {{ issuerGroup?.Issuer_Name }} </p>
      

      但是,在您的最后一次绑定中,由于您调用的是索引,我建议您这样做:

      <p *ngIf="issuerGroups?.length"> Display the Issuer Name here: {{ issuerGroups[0]?.Issuer_Name }} </p>
      

      或类似:

      <p> Display the Issuer Name here: {{ issuerGroups?.length ? issuerGroups[0]?.Issuer_Name : '' }} </p>
      

      但是有很多方法可以做到这一点。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-12-23
        • 1970-01-01
        • 1970-01-01
        • 2020-04-02
        • 1970-01-01
        • 2019-05-06
        • 2018-01-21
        • 1970-01-01
        相关资源
        最近更新 更多