【问题标题】:Angular interpolation error fetching from api从 api 获取角度插值错误
【发布时间】:2020-09-23 11:34:25
【问题描述】:

这是一个项目。我需要从此 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/"}]}

我正在尝试使用插值来迭代模板中的名称。但由于“名称”包含在 api 的“结果”中,因此只有在模板中使用结果时才能访问它。这会产生错误,因此通常无法编译。

我的 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`);

  }

我的课程文件

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>

我得到的错误: 无法读取未定义的属性“链” 和 vendor.js:77062 错误错误:找不到类型为“bulbasaur”的不同支持对象“[object Object]”。 NgFor 只支持绑定到 Arrays 等 Iterables。

【问题讨论】:

    标签: angular api string-interpolation


    【解决方案1】:

    您的错误是因为当您尝试执行*ngForpokemon 为空,对吗?在这种情况下,您可以在 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.。这是因为字段种类不是一个数组而是一个对象,所以你必须使用keyvalue 管道。点击here查看文档

    【讨论】:

    • 我对另一个组件也有类似的问题。我已经附加了代码。你能帮我@Lud 吗?
    • @HeidiE 我回答你了^^
    • 是的,现在一切正常。唯一的问题是,{{res?.value?.name}} 不起作用,但 {{res?.value}} 起作用。谢谢你的帮助@Lud!
    猜你喜欢
    • 1970-01-01
    • 2019-03-04
    • 2015-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-01
    • 2020-07-03
    • 1970-01-01
    相关资源
    最近更新 更多