【问题标题】:How to read a JSON object response from GET request in Angular 9?如何从 Angular 9 中的 GET 请求中读取 JSON 对象响应?
【发布时间】:2020-09-24 14:03:10
【问题描述】:

我有一个GET 请求,它返回以下 JSON 对象:

{
    "success": true,
    "timestamp": 1591353365,
    "base": "EUR",
    "date": "2020-06-05",
    "rates": {
        "AED": 4.16005,
        "AFN": 85.969034,
        "ALL": 124.045327,
        "AMD": 540.380668,
        "ANG": 2.009928,
    }
}

为了获得这个角度的响应,我有一个服务,它使用 API 来检索这个对象,使用 http.get():

import { Injectable } from '@angular/core';
import { HttpClient } from "@angular/common/http";

@Injectable({
  providedIn: 'root'
})
export class ForexService {

  api_key = 'my personal key' //Can't give away the key

  constructor(private _http: HttpClient) { }

  latestRates() {
    return this._http.get('http://data.fixer.io/api/latest?access_key='+this.api_key);
  }
}

而且我有一个订阅该服务的组件文件可观察:

import { Component, OnInit } from '@angular/core';
import { ForexService } from "../forex.service";

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

  data:Array<any>;
  constructor(private forex: ForexService) {
    console.log('Forex component constructor called');
  }

  ngOnInit(): void {
    this.forex.latestRates().subscribe(data => this.data = data);
    }
  }

当我这样做时,我得到The 'Object' type is assignable to very few other types. Did you mean to use the 'any' type instead?的错误

如何从这个 JSON 对象中检索数据? rates 是另一个对象,长度可变。我似乎无法检索该数据。

【问题讨论】:

  • 要么声明 data:Array&lt;any&gt;=[] 然后推送 ,this.data.push(data) 要么声明 data:any={}
  • 这只是将未定义的变量推送到数据数组中。我仍然无法解析它:(

标签: json angular typescript


【解决方案1】:

使用 Angular 2+ 的好处是它使用了TypeScript,而且您还可以在代码中使用强大的typing,例如像这样定义您的 latestRate 的返回类型:

 latestRates(): Observable<Rate[]> {
 return this._http.get('http://data.fixer.io/api/latest?access_key='+this.api_key)
    .map(result=>result.rates)

 }

同时创建rate 的模型,类似于rate.model.ts 并将其定义为响应对象rate(您从API 端点获取的对象):

export interface ResponseObject {
  success: number;
  timestamp: string;
  base: string;
  date: Date;
  rates: Rate;
 }
export interface Rate  {
    aed: number;
    afn: number;
    all: number;
}

另存为rate.model.ts。之后,在您的 ngOnInit 中:

ngOnInit(): void {
      this.forex.latestRates().subscribe(rates => this.data = rates);
}

旁注:尽量避免将any 用作type

【讨论】:

  • 对不起,我不明白我创建费率模型的部分。你能解释清楚一点吗?
  • @smithnblack 类不适合声明表示 HTTP 响应的类型,因为 HTTP 请求产生的反序列化 JSON 值永远不会是类的实例。接口是它的完美候选者。
  • 如何在JSON对象data中为rates对象定义一个变量?
【解决方案2】:

问题在于ForexapiComponent 中的data 变量数据类型;

您的返回响应将数据作为对象,但您将 data 变量声明为项目数组,因此 Typescript 将期待项目数组而不是对象

为了快速修复,您可以将 data 的类型更改为类似 data:any 的任何类型

【讨论】:

  • 但是当我这样做时,它不会存储任何数据并显示数据未定义。控制台错误为:ERROR TypeError: Cannot read property 'rates' of undefined
  • 试试this.forex.latestRates().subscribe(data =&gt; this.data = JSON.parse(data));
  • 数据不是字符串,而是 JSON 对象。如何解析 JSON 对象?我是 JavaScript 新手。我不知道该怎么做:(
  • JSON.parse 将解析为 js 对象..这就是我在之前的评论中提到的
  • 这是错误:Argument of type 'Object' is not assignable to parameter of type 'string'. this.forex.latestRates().subscribe(data =&gt; this.data = JSON.parse(data));
【解决方案3】:

您将 data 定义为 data:Array&lt;any&gt;; 即一个数组

但是你得到的数据是JSON Object

使用data:any;

【讨论】:

    【解决方案4】:

    显然,这是一个异步回复,因此可以使用 async-wait 方法解决。

    这就是我在服务中更改代码的方式:

    latestRates(base: string = "USD"): Promise<any> {
        //return this._http.get('http://data.fixer.io/api/latest? access_key='+this.api_key+'&base='+base).toPromise();
        return this._http.get('https://api.exchangeratesapi.io/latest?base='+base).toPromise();
      }
    
    

    而接收函数长这样:

    data:any;
    async requestData(base) {
        this.data = await this.forex.latestRates(base);
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-04
      • 2017-08-22
      • 1970-01-01
      • 2016-08-25
      • 1970-01-01
      相关资源
      最近更新 更多