问题
I would like to get each key value pair in the results object from my api to display on my front-end. ie(category, type, difficulty, questions correct_answer) I have the service and components set up correctly and all i need to do is fetch the json and display each pair. The method name is called fetchQuestions as seen below. I was able to successfully get data by just simply calling it the same way I did fetchPeople but the json format is not the same so it's not displaying. I then tried something else but that's not working either. How can I acheive displaying this?
People.service
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"
]
}
]
}
People.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() {
}
}
People.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:
The HTTP GET is a cold observable. As such each async
will fire an individual request. Besides you aren't actually returning the observable from the fetchQuestions()
function. The subscription should be removed.
You could also use Angular HttpParams to set the query parameters and do things the Angular way.
Try the following
Service
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));
}
Template
<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>
I also noticed a small type. result.questions
should actually be result.question
.
More details about hot vs cold observables: https://blog.thoughtram.io/angular/2016/06/16/cold-vs-hot-observables.html
Working example: Stackblitz
来源:https://stackoverflow.com/questions/61510211/im-trying-to-get-key-value-pairs-from-json-data-via-an-external-api-and-display