Angular 从 api 获取插值错误
Angular interpolation error fetching from api
这是一个项目。我需要从这个 api: https://pokeapi.co/ 访问一个数组。我能够访问数组,它看起来像这样:
{"count":1050,"next":"https://pokeapi.co/api/v2/pokemon?offset=20&limit=20","previous":null,"results":[{"name":"bulbasaur","url":"https://pokeapi.co/api/v2/pokemon/1/"},{"name":"ivysaur","url":"https://pokeapi.co/api/v2/pokemon/2/"},{"name":"venusaur","url":"https://pokeapi.co/api/v2/pokemon/3/"},{"name":"charmander","url":"https://pokeapi.co/api/v2/pokemon/4/"},{"name":"charmeleon","url":"https://pokeapi.co/api/v2/pokemon/5/"},{"name":"charizard","url":"https://pokeapi.co/api/v2/pokemon/6/"},{"name":"squirtle","url":"https://pokeapi.co/api/v2/pokemon/7/"},{"name":"wartortle","url":"https://pokeapi.co/api/v2/pokemon/8/"},{"name":"blastoise","url":"https://pokeapi.co/api/v2/pokemon/9/"},{"name":"caterpie","url":"https://pokeapi.co/api/v2/pokemon/10/"},{"name":"metapod","url":"https://pokeapi.co/api/v2/pokemon/11/"},{"name":"butterfree","url":"https://pokeapi.co/api/v2/pokemon/12/"},{"name":"weedle","url":"https://pokeapi.co/api/v2/pokemon/13/"},{"name":"kakuna","url":"https://pokeapi.co/api/v2/pokemon/14/"},{"name":"beedrill","url":"https://pokeapi.co/api/v2/pokemon/15/"},{"name":"pidgey","url":"https://pokeapi.co/api/v2/pokemon/16/"},{"name":"pidgeotto","url":"https://pokeapi.co/api/v2/pokemon/17/"},{"name":"pidgeot","url":"https://pokeapi.co/api/v2/pokemon/18/"},{"name":"rattata","url":"https://pokeapi.co/api/v2/pokemon/19/"},{"name":"raticate","url":"https://pokeapi.co/api/v2/pokemon/20/"}]}
我正在尝试使用插值来迭代模板中的名称。但由于 'name' 包裹在 api 上的 'results' 中,只有在模板中使用结果才能到达它。这会产生错误,结果通常不会编译。
我的ts文件
import { Component, OnInit } from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {PokemonData} from '../../models/pokemon';
import {PokemonService} from '../../models/services/pokemon.service';
@Component({
selector: 'app-pokemon-data',
templateUrl: './pokemon-data.component.html',
styleUrls: ['./pokemon-data.component.css']
})
export class PokemonDataComponent implements OnInit {
// @Input() id: string;
public pokemonData: PokemonData[] = [];
private name: string;
constructor(private pokemonService: PokemonService, private route: ActivatedRoute) {
this.name = this.route.snapshot.paramMap.get('name');
}
onLoadPokemonByName(): void {
this.pokemonService.getPokemonbyName(this.name).subscribe(
res => {
console.log(this.name);
this.pokemonData = JSON.parse(JSON.stringify(res));
console.log(this.pokemonData);
}
);
}
ngOnInit(): void {
this.onLoadPokemonByName();
}
}
这是 html 文件
<p>pokemon works!</p>
<div *ngFor="let res of pokemon.results">
<div>{{res.name}}, {{res.url}}</div>
<button routerLink="/pokemondata/{{res.name}}">Pokemon Details</button>
</div>
这是服务文件
import { Injectable } from '@angular/core';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';
import {HttpClient} from '@angular/common/http';
import {Pokemon, PokemonData} from '../pokemon';
@Injectable({
providedIn: 'root'
})
export class PokemonService {
constructor(private http: HttpClient) {
}
// http call
private baseUrl = 'https://pokeapi.co/api/v2/';
getPokemonList(): Observable<Pokemon[]> {
return this.http.get<Pokemon[]>(this.baseUrl + `pokemon?limit=150`);
}
我的class文件
export class Pokemon {
// this class contains properties that contain information on Pokemons
name: string;
url: string;
results: Result[];
}
export interface Result {
results: Result[];
}
我的问题:如何实例化结果以使 i5 不会在模板中导致错误。
额外的 ts 文件
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material/dialog';
import {PokemonService} from '../../models/services/pokemon.service';
import {PokemonData} from '../../models/pokemon';
import {Chain, Evolution, Species} from '../../models/evolution';
import {ActivatedRoute} from '@angular/router';
@Component({
selector: 'app-evolution',
templateUrl: './evolution.component.html',
styleUrls: ['./evolution.component.css']
})
export class EvolutionComponent implements OnInit {
evolution: Evolution;
species: Species;
chain: Chain;
private id: string;
constructor(private pokemonService: PokemonService,
private route: ActivatedRoute) {
this.id = this.route.snapshot.paramMap.get('id');
}
getEvolutionDetails(): void {
this.pokemonService.getEvolutionData(this.id).subscribe((
res => {
console.log(this.id);
this.evolution = JSON.parse(JSON.stringify(res));
console.log(this.evolution);
}
));
}
ngOnInit(): void {
this.getEvolutionDetails();
}
}
html 文件
<p *ngIf="evolution.chain.species">
<div *ngFor="let res of evolution.chain.species">{{res.name}} </div>
我得到的错误:
无法读取未定义的 属性 'chain'
和
vendor.js:77062 错误错误:找不到类型为 'bulbasaur' 的不同支持对象“[object Object]”。 NgFor 仅支持绑定到 Iterables,例如 Arrays。
您的错误是因为当您尝试执行 *ngFor
时 pokemon
为空?在这种情况下,您可以在 HTML.
中的 pokemon
之后添加 ?
<div *ngFor="let res of pokemon?.results">
<div>{{res.name}}, {{res.url}}</div>
<button routerLink="/pokemondata/{{res.name}}">Pokemon Details</button>
</div>
为了确保您有结果,最好在 res
之后添加 ?
。
<div *ngFor="let res of pokemon?.results">
<div>{{res?.name}}, {{res?.url}}</div>
<button routerLink="/pokemondata/{{res?.name}}">Pokemon Details</button>
</div>
或者你可以做一个 if
<ng-container *ngIf="pokemon">
<div *ngFor="let res of pokemon?.results">
<div>{{res?.name}}, {{res?.url}}</div>
<button routerLink="/pokemondata/{{res?.name}}">Pokemon Details</button>
</div>
</ng-container>
对于你的 EvolutionComponent
的第二个错误,你有 2 个错误:
<p *ngIf="evolution.chain.species">
<div *ngFor="let res of evolution.chain.species">{{res.name}} </div>
要修复它们,您可以这样做:
<p *ngIf="evolution?.chain?.species">
<div *ngFor="let res of evolution?.chain?.species | keyvalue">{{res?.value?.name}} </div>
?
是检查值是否不为空
对于错误NgFor only supports binding to Iterables such as Arrays.
。这是因为字段 species 不是数组而是对象,因此您必须使用 keyvalue
管道。单击 here 获取文档
这是一个项目。我需要从这个 api: https://pokeapi.co/ 访问一个数组。我能够访问数组,它看起来像这样:
{"count":1050,"next":"https://pokeapi.co/api/v2/pokemon?offset=20&limit=20","previous":null,"results":[{"name":"bulbasaur","url":"https://pokeapi.co/api/v2/pokemon/1/"},{"name":"ivysaur","url":"https://pokeapi.co/api/v2/pokemon/2/"},{"name":"venusaur","url":"https://pokeapi.co/api/v2/pokemon/3/"},{"name":"charmander","url":"https://pokeapi.co/api/v2/pokemon/4/"},{"name":"charmeleon","url":"https://pokeapi.co/api/v2/pokemon/5/"},{"name":"charizard","url":"https://pokeapi.co/api/v2/pokemon/6/"},{"name":"squirtle","url":"https://pokeapi.co/api/v2/pokemon/7/"},{"name":"wartortle","url":"https://pokeapi.co/api/v2/pokemon/8/"},{"name":"blastoise","url":"https://pokeapi.co/api/v2/pokemon/9/"},{"name":"caterpie","url":"https://pokeapi.co/api/v2/pokemon/10/"},{"name":"metapod","url":"https://pokeapi.co/api/v2/pokemon/11/"},{"name":"butterfree","url":"https://pokeapi.co/api/v2/pokemon/12/"},{"name":"weedle","url":"https://pokeapi.co/api/v2/pokemon/13/"},{"name":"kakuna","url":"https://pokeapi.co/api/v2/pokemon/14/"},{"name":"beedrill","url":"https://pokeapi.co/api/v2/pokemon/15/"},{"name":"pidgey","url":"https://pokeapi.co/api/v2/pokemon/16/"},{"name":"pidgeotto","url":"https://pokeapi.co/api/v2/pokemon/17/"},{"name":"pidgeot","url":"https://pokeapi.co/api/v2/pokemon/18/"},{"name":"rattata","url":"https://pokeapi.co/api/v2/pokemon/19/"},{"name":"raticate","url":"https://pokeapi.co/api/v2/pokemon/20/"}]}
我正在尝试使用插值来迭代模板中的名称。但由于 'name' 包裹在 api 上的 'results' 中,只有在模板中使用结果才能到达它。这会产生错误,结果通常不会编译。
我的ts文件
import { Component, OnInit } from '@angular/core';
import {ActivatedRoute} from '@angular/router';
import {PokemonData} from '../../models/pokemon';
import {PokemonService} from '../../models/services/pokemon.service';
@Component({
selector: 'app-pokemon-data',
templateUrl: './pokemon-data.component.html',
styleUrls: ['./pokemon-data.component.css']
})
export class PokemonDataComponent implements OnInit {
// @Input() id: string;
public pokemonData: PokemonData[] = [];
private name: string;
constructor(private pokemonService: PokemonService, private route: ActivatedRoute) {
this.name = this.route.snapshot.paramMap.get('name');
}
onLoadPokemonByName(): void {
this.pokemonService.getPokemonbyName(this.name).subscribe(
res => {
console.log(this.name);
this.pokemonData = JSON.parse(JSON.stringify(res));
console.log(this.pokemonData);
}
);
}
ngOnInit(): void {
this.onLoadPokemonByName();
}
}
这是 html 文件
<p>pokemon works!</p>
<div *ngFor="let res of pokemon.results">
<div>{{res.name}}, {{res.url}}</div>
<button routerLink="/pokemondata/{{res.name}}">Pokemon Details</button>
</div>
这是服务文件
import { Injectable } from '@angular/core';
import {Observable} from 'rxjs';
import {map} from 'rxjs/operators';
import {HttpClient} from '@angular/common/http';
import {Pokemon, PokemonData} from '../pokemon';
@Injectable({
providedIn: 'root'
})
export class PokemonService {
constructor(private http: HttpClient) {
}
// http call
private baseUrl = 'https://pokeapi.co/api/v2/';
getPokemonList(): Observable<Pokemon[]> {
return this.http.get<Pokemon[]>(this.baseUrl + `pokemon?limit=150`);
}
我的class文件
export class Pokemon {
// this class contains properties that contain information on Pokemons
name: string;
url: string;
results: Result[];
}
export interface Result {
results: Result[];
}
我的问题:如何实例化结果以使 i5 不会在模板中导致错误。
额外的 ts 文件
import {Component, Inject, OnInit} from '@angular/core';
import {MAT_DIALOG_DATA, MatDialog, MatDialogRef} from '@angular/material/dialog';
import {PokemonService} from '../../models/services/pokemon.service';
import {PokemonData} from '../../models/pokemon';
import {Chain, Evolution, Species} from '../../models/evolution';
import {ActivatedRoute} from '@angular/router';
@Component({
selector: 'app-evolution',
templateUrl: './evolution.component.html',
styleUrls: ['./evolution.component.css']
})
export class EvolutionComponent implements OnInit {
evolution: Evolution;
species: Species;
chain: Chain;
private id: string;
constructor(private pokemonService: PokemonService,
private route: ActivatedRoute) {
this.id = this.route.snapshot.paramMap.get('id');
}
getEvolutionDetails(): void {
this.pokemonService.getEvolutionData(this.id).subscribe((
res => {
console.log(this.id);
this.evolution = JSON.parse(JSON.stringify(res));
console.log(this.evolution);
}
));
}
ngOnInit(): void {
this.getEvolutionDetails();
}
}
html 文件
<p *ngIf="evolution.chain.species">
<div *ngFor="let res of evolution.chain.species">{{res.name}} </div>
我得到的错误: 无法读取未定义的 属性 'chain' 和 vendor.js:77062 错误错误:找不到类型为 'bulbasaur' 的不同支持对象“[object Object]”。 NgFor 仅支持绑定到 Iterables,例如 Arrays。
您的错误是因为当您尝试执行 *ngFor
时 pokemon
为空?在这种情况下,您可以在 HTML.
pokemon
之后添加 ?
<div *ngFor="let res of pokemon?.results">
<div>{{res.name}}, {{res.url}}</div>
<button routerLink="/pokemondata/{{res.name}}">Pokemon Details</button>
</div>
为了确保您有结果,最好在 res
之后添加 ?
。
<div *ngFor="let res of pokemon?.results">
<div>{{res?.name}}, {{res?.url}}</div>
<button routerLink="/pokemondata/{{res?.name}}">Pokemon Details</button>
</div>
或者你可以做一个 if
<ng-container *ngIf="pokemon">
<div *ngFor="let res of pokemon?.results">
<div>{{res?.name}}, {{res?.url}}</div>
<button routerLink="/pokemondata/{{res?.name}}">Pokemon Details</button>
</div>
</ng-container>
对于你的 EvolutionComponent
的第二个错误,你有 2 个错误:
<p *ngIf="evolution.chain.species">
<div *ngFor="let res of evolution.chain.species">{{res.name}} </div>
要修复它们,您可以这样做:
<p *ngIf="evolution?.chain?.species">
<div *ngFor="let res of evolution?.chain?.species | keyvalue">{{res?.value?.name}} </div>
?
是检查值是否不为空
对于错误NgFor only supports binding to Iterables such as Arrays.
。这是因为字段 species 不是数组而是对象,因此您必须使用 keyvalue
管道。单击 here 获取文档