在我的 angular 应用中 API 调用 JokeAPI 时遇到 Observe/Subscribe 问题
Having trouble with Observe/Subscribe on API call to JokeAPI in my angular app
我现在已经在这上面花费了 3 天的大部分时间,我只知道这将是一件愚蠢的事情。
我的 api 呼叫正常,我收到了回复,但我的 ngFor 循环让我头疼这个错误:
大家可以看到我的API在图片下方返回了一个数据包。我用在 home 组件中加载 fin 的标准 div 测试了组件,所以我知道这不是问题。据我所知,尽管我正在使用观察和订阅,但看起来 ngFor 循环正在尝试 运行 之前数据从调用返回。
这是我的打字稿文件:
//joke.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';
@Injectable({providedIn: 'root'})
export class JokesService {
//service api
apiURL = 'https://v2.jokeapi.dev/joke/';
constructor(private http: HttpClient) {}
//optional filters
numJokes = 10;
//add more than one category using comma separation
categories = 'Programming'; //options: Programming,Misc,Dark,Pun,Spooky,Christmas or 'Any' for all categories
//add more than one flag using comma separation
blacklistFlags = 'nsfw,racist,sexist,explicit'; //options: explicit,nsfw,political,racist,religious,sexist
getJokes() {
function getTypeName(val) {
return {}.toString.call(val).slice(8, -1);
}
return this.http
.get(`${this.apiURL}${this.categories}?blacklistFlags=${this.blacklistFlags}&amount=${this.numJokes}`)
.pipe(map(data => {
const jokesArr = [];
for (let i=0; i<10; i++) {
jokesArr.push(data['jokes'][i]);
}
return jokesArr;
}))
.subscribe(data => console.log("Payload = ", getTypeName(data), data));
}
}
//joke-scroll.component.ts
import { Component, OnInit } from '@angular/core';
import { JokesService } from '../../../jokes.service';
@Component({
selector: 'app-joke-scroll',
templateUrl: './joke-scroll.component.html',
styleUrls: ['./joke-scroll.component.sass']
})
export class JokeScrollComponent implements OnInit {
jokesArr;
constructor(private jokesService: JokesService) { }
ngOnInit(): void {
this.jokesArr = this.jokesService.getJokes();
console.log(this.jokesArr);
}
}
//joke-scroll.component.html
<div class='box scrollingText' *ngFor="let joke of jokesArr">
<p *ngIf=""></p>
<p *ngIf="joke.type == 'twopart'"> Q: {{ joke.setup }} A: {{ joke.delivery }}</p>
<p *ngIf="joke.type == 'single'"> {{ joke.joke }} </p>
</div>
如有任何帮助,我们将不胜感激。
订阅服务不是一个好主意。最好把它做成组件。您也可以更自由地对其进行自定义。如果你想修复上面的代码,你可以使用 async await,但仍然不推荐它。
我能够通过绑定数据并在服务调用开始时删除 return 命令来解决问题。将管道函数留在服务调用中 return 根据需要编辑数据。这是我更新的代码:
//joke.service.ts
import { Component, OnInit } from '@angular/core';
import { JokesService } from '../../../jokes.service';
@Component({
selector: 'app-joke-scroll',
templateUrl: './joke-scroll.component.html',
styleUrls: ['./joke-scroll.component.sass']
})
export class JokeScrollComponent implements OnInit {
jokesArr;
dataReady:boolean = false;
constructor(private jokesService: JokesService) { }
ngOnInit(): void {
function getTypeName(val) {
return {}.toString.call(val).slice(8, -1);
}
this.jokesService.getJokes().subscribe(data => this.jokesArr = data);
//console.log("Payload = ", getTypeName(data), data);
//console.log(this.jokesArr);
}
//joke-scroll.component.ts
import { Component, OnInit } from '@angular/core';
import { JokesService } from '../../../jokes.service';
@Component({
selector: 'app-joke-scroll',
templateUrl: './joke-scroll.component.html',
styleUrls: ['./joke-scroll.component.sass']
})
export class JokeScrollComponent implements OnInit {
jokesArr;
dataReady:boolean = false;
constructor(private jokesService: JokesService) { }
ngOnInit(): void {
function getTypeName(val) {
return {}.toString.call(val).slice(8, -1);
}
this.jokesService.getJokes().subscribe(data => this.jokesArr = data);
//console.log("Payload = ", getTypeName(data), data);
//console.log(this.jokesArr);
}
//joke-scroll.component.html
<div class='box scrollingText' *ngFor="let joke of jokesArr">
<p *ngIf="joke.type == 'twopart'"> Q: {{ joke.setup }} A: {{ joke.delivery }}</p>
<p *ngIf="joke.type == 'single'"> {{ joke.joke }} </p>
</div>
现在我只需要修复它,这样我就可以得到一行 10 个滚动笑话,而不是 10 行单个滚动笑话。谢谢各位指点。
我现在已经在这上面花费了 3 天的大部分时间,我只知道这将是一件愚蠢的事情。 我的 api 呼叫正常,我收到了回复,但我的 ngFor 循环让我头疼这个错误:
大家可以看到我的API在图片下方返回了一个数据包。我用在 home 组件中加载 fin 的标准 div 测试了组件,所以我知道这不是问题。据我所知,尽管我正在使用观察和订阅,但看起来 ngFor 循环正在尝试 运行 之前数据从调用返回。 这是我的打字稿文件:
//joke.service.ts
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { map } from 'rxjs/operators';
@Injectable({providedIn: 'root'})
export class JokesService {
//service api
apiURL = 'https://v2.jokeapi.dev/joke/';
constructor(private http: HttpClient) {}
//optional filters
numJokes = 10;
//add more than one category using comma separation
categories = 'Programming'; //options: Programming,Misc,Dark,Pun,Spooky,Christmas or 'Any' for all categories
//add more than one flag using comma separation
blacklistFlags = 'nsfw,racist,sexist,explicit'; //options: explicit,nsfw,political,racist,religious,sexist
getJokes() {
function getTypeName(val) {
return {}.toString.call(val).slice(8, -1);
}
return this.http
.get(`${this.apiURL}${this.categories}?blacklistFlags=${this.blacklistFlags}&amount=${this.numJokes}`)
.pipe(map(data => {
const jokesArr = [];
for (let i=0; i<10; i++) {
jokesArr.push(data['jokes'][i]);
}
return jokesArr;
}))
.subscribe(data => console.log("Payload = ", getTypeName(data), data));
}
}
//joke-scroll.component.ts
import { Component, OnInit } from '@angular/core';
import { JokesService } from '../../../jokes.service';
@Component({
selector: 'app-joke-scroll',
templateUrl: './joke-scroll.component.html',
styleUrls: ['./joke-scroll.component.sass']
})
export class JokeScrollComponent implements OnInit {
jokesArr;
constructor(private jokesService: JokesService) { }
ngOnInit(): void {
this.jokesArr = this.jokesService.getJokes();
console.log(this.jokesArr);
}
}
//joke-scroll.component.html
<div class='box scrollingText' *ngFor="let joke of jokesArr">
<p *ngIf=""></p>
<p *ngIf="joke.type == 'twopart'"> Q: {{ joke.setup }} A: {{ joke.delivery }}</p>
<p *ngIf="joke.type == 'single'"> {{ joke.joke }} </p>
</div>
如有任何帮助,我们将不胜感激。
订阅服务不是一个好主意。最好把它做成组件。您也可以更自由地对其进行自定义。如果你想修复上面的代码,你可以使用 async await,但仍然不推荐它。
我能够通过绑定数据并在服务调用开始时删除 return 命令来解决问题。将管道函数留在服务调用中 return 根据需要编辑数据。这是我更新的代码:
//joke.service.ts
import { Component, OnInit } from '@angular/core';
import { JokesService } from '../../../jokes.service';
@Component({
selector: 'app-joke-scroll',
templateUrl: './joke-scroll.component.html',
styleUrls: ['./joke-scroll.component.sass']
})
export class JokeScrollComponent implements OnInit {
jokesArr;
dataReady:boolean = false;
constructor(private jokesService: JokesService) { }
ngOnInit(): void {
function getTypeName(val) {
return {}.toString.call(val).slice(8, -1);
}
this.jokesService.getJokes().subscribe(data => this.jokesArr = data);
//console.log("Payload = ", getTypeName(data), data);
//console.log(this.jokesArr);
}
//joke-scroll.component.ts
import { Component, OnInit } from '@angular/core';
import { JokesService } from '../../../jokes.service';
@Component({
selector: 'app-joke-scroll',
templateUrl: './joke-scroll.component.html',
styleUrls: ['./joke-scroll.component.sass']
})
export class JokeScrollComponent implements OnInit {
jokesArr;
dataReady:boolean = false;
constructor(private jokesService: JokesService) { }
ngOnInit(): void {
function getTypeName(val) {
return {}.toString.call(val).slice(8, -1);
}
this.jokesService.getJokes().subscribe(data => this.jokesArr = data);
//console.log("Payload = ", getTypeName(data), data);
//console.log(this.jokesArr);
}
//joke-scroll.component.html
<div class='box scrollingText' *ngFor="let joke of jokesArr">
<p *ngIf="joke.type == 'twopart'"> Q: {{ joke.setup }} A: {{ joke.delivery }}</p>
<p *ngIf="joke.type == 'single'"> {{ joke.joke }} </p>
</div>
现在我只需要修复它,这样我就可以得到一行 10 个滚动笑话,而不是 10 行单个滚动笑话。谢谢各位指点。