Angular: 如何使用服务从服务器获取数据并存储在数组中?

Angular: How to use a Service to fetch data from server and store in an array?

我有一项服务在 https://pokeapi.co/api/v2/pokemon/ 调用 PokéAPI

如果您没有指定想要 return 的 Pokemon,API 将 return 一个分页的资源列表,其中包含 Pokemon 的 URL。 https://pokeapi.co/docs/v2#pokemon-section

我想将该 URL 列表存储在我的服务的本地数组中。

我试过:

getListOfPokemonUrls(): Observable<any> {
    return this.http.get<any>(this.pokeApiUrl)
      .pipe(
        map((response: any[]) => this.pokemonResources = response.results)
      );
  }

在我的构造函数中(用于测试目的):

const y = this.getListOfPokemonUrls();

但是,当我跨过该函数时 this.pokemonResources 数组为空。

要点

  • 使用可观察对象时,请务必subscribe()
  • 与其将服务器响应存储在局部变量中,不如 return 数据以便订阅 Observable 的调用者可以决定如何处理数据。这样做的好处是异步过程一完成,数据就立即可用。

查看工作 Stackblitz Demo

关于 StackBlitz 演示的注释

  1. 创建了一个 Angular 服务 PokeAPIService 在构造函数中调用 PokeAPI 服务器。
  constructor(private http: HttpClient) {
    this.getListOfPokemonUrls().subscribe(
      (results: Array<Pokemon>) => {
        for(let p of results) {
          this.pokemons.push(p)
        }
      }
    )
  }

请注意 getListOfPokemonURLs return 的结果的更新实现,以便可以在对 subscribe() 的调用中处理它们。

  1. PokemonPokeAPIResponse 定义的接口:
export interface Pokemon {
  name: string,
  url: string
}


interface PokeAPIResponse {
  count: number,
  next: string,
  previous: string,
  results: Array<Pokemon>
}
  1. 使用新的接口类型更新 getListOfPokemonUrls() 并修改 RxJS map 以便 response.results 直接 returned。
 private getListOfPokemonUrls(): Observable<Array<Pokemon>> {
    return this.http.get<any>(POKEAPI_URL)
      .pipe(
        map((response: PokeAPIResponse) => response.results)
      );
  }

作为参考,PokeAPI 服务器响应:

curl https://pokeapi.co/api/v2/pokemon/

Returns 以下回复:

{
  "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/"},
...