我正在尝试通过外部 api 从 json 数据中获取键值对并使用 angular 和 typescript 显示它。我怎样才能做到这一点?
Posted
技术标签:
【中文标题】我正在尝试通过外部 api 从 json 数据中获取键值对并使用 angular 和 typescript 显示它。我怎样才能做到这一点?【英文标题】:I'm Trying to get key value pairs from json data via an external api and display it using angular and typescript. How can I achieve this? 【发布时间】:2020-08-14 00:54:44 【问题描述】:我想从我的 api 获取结果对象中的每个键值对以显示在我的前端。即(类别、类型、难度、问题正确答案)我已经正确设置了服务和组件,我需要做的就是获取 json 并显示每一对。方法名称称为 fetchQuestions,如下所示。我只需像 fetchPeople 一样简单地调用它,就能够成功获取数据,但 json 格式不一样,所以它不显示。然后我尝试了其他方法,但这也不起作用。我怎样才能显示这个?
人员.服务
import Injectable from '@angular/core';
import Observable from 'rxjs/Observable';
import HttpClient from '@angular/common/http';
import map from 'rxjs/operators';
@Injectable(
providedIn: 'root'
)
export class PeopleService
constructor(private http: HttpClient)
//this works like a charm as it is just a simple array
fetchPeople(): Observable <Object>
return this.http.get('/assets/data/people.json')
// this doesn't work as the json from the api below is in a different
// json format. Plus I need to return all value pairs
fetchQuestions(): Observable <Object>
return this.http.get('https://opentdb.com/api.php?
amount=10&difficulty=hard&type=boolean').map(res =>
res.json().results).subscribe(data =>
console.log(data););
API https://opentdb.com/api.php?amount=10&difficulty=hard&type=boolean
"response_code": 0,
"results": [
"category": "Vehicles",
"type": "boolean",
"difficulty": "hard",
"question": "In 1993 Swedish car manufacturer Saab experimented
with replacing the steering wheel with a joystick in a Saab 9000.",
"correct_answer": "True",
"incorrect_answers": [
"False"
]
,
"category": "History",
"type": "boolean",
"difficulty": "hard",
"question": "Japan was part of the Allied Powers during World War
I.",
"correct_answer": "True",
"incorrect_answers": [
"False"
]
,
"category": "History",
"type": "boolean",
"difficulty": "hard",
"question": "The Kingdom of Prussia briefly held land in Estonia.",
"correct_answer": "False",
"incorrect_answers": [
"True"
]
,
"category": "Science: Mathematics",
"type": "boolean",
"difficulty": "hard",
"question": "The binary number "101001101" is equivalent
to the Decimal number "334"",
"correct_answer": "False",
"incorrect_answers": [
"True"
]
,
"category": "Entertainment: Video Games",
"type": "boolean",
"difficulty": "hard",
"question": "TF2: Sentry rocket damage falloff is calculated based
on the distance between the sentry and the enemy, not the engineer
and the enemy",
"correct_answer": "False",
"incorrect_answers": [
"True"
]
,
"category": "Entertainment: Video Games",
"type": "boolean",
"difficulty": "hard",
"question": "The names of Roxas's Keyblades in Kingdom Hearts
are "Oathkeeper" and "Oblivion".",
"correct_answer": "True",
"incorrect_answers": [
"False"
]
,
"category": "Entertainment: Music",
"type": "boolean",
"difficulty": "hard",
"question": "The band STRFKR was also briefly known as Pyramiddd.",
"correct_answer": "True",
"incorrect_answers": [
"False"
]
,
"category": "Entertainment: Books",
"type": "boolean",
"difficulty": "hard",
"question": "Harry Potter was born on July 31st, 1980.",
"correct_answer": "True",
"incorrect_answers": [
"False"
]
,
"category": "Entertainment: Japanese Anime & Manga",
"type": "boolean",
"difficulty": "hard",
"question": "Druid is a mage class in "Log Horizon".",
"correct_answer": "False",
"incorrect_answers": [
"True"
]
,
"category": "Geography",
"type": "boolean",
"difficulty": "hard",
"question": "The two largest ethnic groups of Belgium are Flemish and Walloon. ",
"correct_answer": "True",
"incorrect_answers": [
"False"
]
]
人物.page.ts
import Component, OnInit from '@angular/core';
import PeopleService from './../../providers/people.service'
@Component(
selector: 'app-people',
templateUrl: './people.page.html',
styleUrls: ['./people.page.scss'],
)
export class PeoplePage implements OnInit
people$;
results$;
constructor(private peopleService:PeopleService)
fetchPeople()
this.people$ = this.peopleService.fetchPeople();
fetchQuestions()
this.results$ = this.peopleService.fetchQuestions()
ngOnInit()
人物.page.html
<ion-toolbar>
<ion-title>people</ion-title>
</ion-toolbar>
</ion-header>
<ion-button (click) ="fetchPeople()" color="primary">Primary</ion-
button>
<ion-list>
<ion-item *ngFor="let person of people$ | async">person.name.
</ion-item>
</ion-list>
<ion-button (click) ="fetchQuestions()"
color="primary">Secondary</ion-button>
<ion-list>
<ion-item *ngFor="let result of results$ | async">.
result.category</ion-item>
<ion-item *ngFor="let result of results$ | async">
result.questions</ion-item>
<ion-item *ngFor="let result of results$ | async">
result.difficulty</ion-item>
<ion-item *ngFor="let result of results$ | async">
result.correct_answer</ion-item>
</ion-list>
<ion-content>
<ion-button color="primary">Primary</ion-button>
</ion-content>
【问题讨论】:
【参考方案1】:HTTP GET 是一个冷的 observable。因此,每个async
都会触发一个单独的请求。此外,您实际上并没有从 fetchQuestions()
函数返回 observable。应删除订阅。
您也可以使用 Angular HttpParams
设置查询参数并以 Angular 方式执行操作。
试试下面的
服务
import HttpClient, HttpParams from '@angular/common/http';
fetchQuestions(): Observable<any>
const params = new HttpParams()
.set('amount', '10')
.set('difficulty', 'hard')
.set('type', 'boolean');
return this.http.get('https://opentdb.com/api.php', params: params )
.pipe(map(res => res.results));
模板
<ng-container *ngFor="let result of results$ | async">
<ion-list>
<ion-item>result.category</ion-item>
<ion-item>result.question</ion-item>
<ion-item>result.difficulty</ion-item>
<ion-item>result.correct_answer</ion-item>
</ion-list>
</ng-container>
我还注意到一个小字体。 result.questions
实际上应该是 result.question
。
关于热与冷可观察的更多细节:https://blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html
工作示例:Stackblitz
【讨论】:
我在尝试 rc/app/providers/people.service.ts:29:26 时收到此错误 - 错误 TS2339:“对象”类型上不存在属性“json”。 29 .pipe(map(res => res.json().results)); 是的,在最新版本中不需要.json()
。试试res => res.results
。我已经更新了答案。
随着更新,我现在得到的属性“结果”在“对象”类型上不存在。 29 .pipe(map(res => res.results));
我在回答中将函数的返回类型更改为Observable<any>
。你还在用Observable<Object>
吗?如果是这样,请尝试使用Observable<any>
。
我正在使用 Observable 以上是关于我正在尝试通过外部 api 从 json 数据中获取键值对并使用 angular 和 typescript 显示它。我怎样才能做到这一点?的主要内容,如果未能解决你的问题,请参考以下文章
Express 和 Nodejs:调用外部 API 的最佳方式
如何从 JSON 获取数据以在 PrimeNG 折线图中使用?