Angular调用API获取JSON响应后如何正确访问返回数据字段
Angular接口返回数据访问失败解决方案
核心问题原因
- 你当前把
datas初始化为空数组,但该API返回的根结构是普通对象,不是数组,根层级直接包含nhits、parameters、records、facet_groups等属性,其中records才是你要遍历的数组。 - HTTP请求是异步执行,请求返回前
datas一直是初始空值,模板直接访问深层属性会触发空指针报错。 - 你写的
data[0][records]存在语法错误:方括号访问对象属性时,字符串属性名必须加引号包裹,且根返回值不是数组,不存在[0]索引。 - 不建议在构造函数中发起HTTP请求,构造函数仅适合做依赖注入,数据请求逻辑应放在
ngOnInit生命周期中,避免初始化时序问题。
正确实现代码
组件类代码调整
import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; @Component({ selector: 'app-fuel-price', templateUrl: './fuel-price.component.html' }) export class FuelPriceComponent implements OnInit { url = 'https://data.economie.gouv.fr/api/records/1.0/search/?dataset=prix-carburants-fichier-instantane-test-ods-copie&q=aire+sur+l%27adour&lang=fr&facet=id&facet=adresse&facet=ville&facet=prix_maj&facet=prix_nom&facet=com_arm_name&facet=epci_name&facet=dep_name&facet=reg_name&facet=services_service&facet=horaires_automate_24_24&refine.ville=Aire-sur-l%27Adour'; // 根返回值是对象,初始值设为null做类型标记 responseData: any = null; // 如果只需要遍历records列表,也可以单独定义数组成员 recordsList: any[] = []; constructor(private http: HttpClient) {} ngOnInit(): void { // 把请求移到ngOnInit生命周期 this.http.get(this.url).toPromise().then((res: any) => { this.responseData = res; // 直接从返回根对象取records数组,做容错处理 this.recordsList = res?.records || []; // 控制台打印可以直接看到数组结构,对照字段取值即可 console.log('接口返回records列表:', this.recordsList); }) } }
模板代码调整
模板中必须做空值容错,避免请求未返回时访问属性报错,推荐两种写法:
- 配合手动赋值的变量,用
*ngIf做判断后再渲染
<!-- 先判断数据存在再渲染内部内容 --> <ng-container *ngIf="responseData"> <p>匹配结果总数:{{ responseData.nhits }}</p> <!-- 遍历records数组 --> <div class="record-item" *ngFor="let record of recordsList"> <p>记录ID:{{ record.recordid }}</p> <p>加油站地址:{{ record.fields.adresse }}</p> <p>所在城市:{{ record.fields.ville }}</p> <p>油价更新时间:{{ record.fields.prix_maj }}</p> <!-- 其余字段对照json管道打印出的fields下的属性直接取值即可 --> </div> </ng-container>
- 更推荐用
async管道自动订阅,无需手动销毁订阅,避免内存泄漏
// 组件类中直接定义请求可观察对象 response$ = this.http.get(this.url); constructor(private http: HttpClient) {} // 无需手动写订阅逻辑
<!-- async管道自动处理订阅、空值判断 --> <ng-container *ngIf="response$ | async as res"> <p>匹配结果总数:{{ res.nhits }}</p> <div *ngFor="let record of res.records"> <!-- 字段取值同上 --> </div> </ng-container>
语法注意点
- 对象属性访问两种合法写法:点语法
res.records,或者方括号加引号属性名res['records'],未加引号的res[records]会把records当成变量解析,必然报错。 - 数组才需要用索引取值,比如取第一条记录的地址可以写
recordsList[0].fields.adresse,根返回对象不是数组,不能直接加索引访问。
内容的提问来源于stack exchange,提问作者Antoine Pascual
相关产品推荐
相关产品推荐

