我目前的设置就是这个。
ngOnInIt
的 dashboard.component.ts
运行了databaseService
来订阅结果。
database.service.ts
运行http POST
获取数据并填充值IssuerGroup
。
我想显示我的数据库以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的结果,没有错误。任何帮助将不胜感激。
答案 0 :(得分:1)
您可以在将变量绑定到HTML模板时使用the safe navigation operator
(属性前为?
),如:
{{ issuerGroups?.Issuer_Name }}
只有当 Issuer_Name
存在(不是issuerGroups
或null
)时,全局才会显示undefined
。优点是您不必使用*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>
但是有很多方法可以做到这一点。
答案 1 :(得分: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:
当它们尚未加载时,不要访问异步加载的对象的成员。