使用 http 调用解析可观察属性

Resolve observable properties with http calls

我正在尝试为 public https://pokeapi.co/ 编写一个 API 界面 尝试查询 Pokémon 时,API 不是 return 整个模型,而是 return 是 url 对 children 的引用。

(尝试查询https://pokeapi.co/api/v2/pokemon/name)

而不是预期的

Pokemon { 
  id,
  name,
  types[ (Actual model)
    {
      id,
      name,
      otherProperties...
    }
  ]
} 

我得到

Pokemon { 
  id,
  name,
  types[ (Reference to the actual model)
    {
      name,
      url
    }
  ]
} 

我如何使用 HttpClient 和 rxjs 创建一个方法 findPokemonByName(string: name),它 return 是根神奇宝贝并将类型作为嵌套的 http 请求映射到 https://pokeapi.co/api/v2/type/name

这是服务的预览:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { tap, switchMap } from 'rxjs/operators';
import { forkJoin } from 'rxjs';

@Injectable()
export class PokemonService {
  private baseAPIUrl = 'https://pokeapi.co/api/v2/';
  constructor(private httpClient: HttpClient) {

   }

   public getPokemonByName(name: string) {
     return this.httpClient.get(`${this.baseAPIUrl}pokemon/${name}`)
     .pipe(
       switchMap((pokemon: any) => {
         return forkJoin({
           types: forkJoin(this.generateRequestsForTypes(pokemon.types))
         })
       }, (pokemon, result) => {
         pokemon.types = result.types;
         return pokemon;
       }),
     )
   }

  private getPokemonTypeByUrl(url: string) {
    return this.httpClient.get(url);
  }

  private generateRequestsForTypes(types: any[]) {
    return types.map((type) => this.getPokemonTypeByUrl(type.type.url))
  }
}

当然你必须添加类型,但我认为这可能是一个好的开始。

注意请求的数量,因为每个嵌套 属性 都可以是一个请求。

使用结果选择器函数(上例中 switchMap 运算符的最后一个参数)。

stackblitz