You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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);
    })
  }
}

模板代码调整

模板中必须做空值容错,避免请求未返回时访问属性报错,推荐两种写法:

  1. 配合手动赋值的变量,用*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>
  1. 更推荐用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 06:09:20