Как я могу использовать RxJS для обработки нескольких вызовов API в службе Angular? - PullRequest
0 голосов
/ 29 июня 2018

Проблема: я хочу получить данные из Star Wars Api (SWAPI). Я хочу сделать первоначальный вызов HTTP, а затем в этом же вызове получить значения от 2 дополнительных вызовов API. Swapi возвращает объект json, но его значения также являются ссылками на другие части их API.

В настоящее время этот код работает, но я могу получить только символьный объект, а затем объект домашнего мира.

Вот мой код:

question.service.ts

  getCharacter() {
    const random = Math.floor(Math.random() * 10) + 1;

   let characterUrl = `https://swapi.co/api/people/${random}/`;

   this.http.get(characterUrl).pipe(
    mergeMap((character:any) => {

      this.character = character;

    //I tried using forkJoin(this.http.get(character.species), this.http.get(character.homeworld)), but it wasn't working.

    //In total, I want to get the original character object, and also the species/homeworld values. 

      return this.http.get(character.homeworld);

    })
    //logs out the homeworld value, but I'd also like the species value.
  ).subscribe(v => console.log(v))

  }

Это код, из которого я пытаюсь выполнить рефакторинг:

question.component.ts

   this.questionService.getCharacter().subscribe((character: any) => {
   console.log(character)
    this.http.get(character.homeworld).subscribe((homeworld: any) => {
      this.loadedCharacter = character;

      this.loadedCharacter.homeworld = homeworld.name;

        this.http.get(character.species[0]).subscribe((species: any) => {
        this.loadedCharacter.species = species.name;
        this.makeQuestions();
    });
    });
  });

Пример SWAPI-объекта json:

{
    "birth_year": "19 BBY",
    "eye_color": "Blue",
    "films": [
        "https://swapi.co/api/films/1/",
        ...
    ],
    "gender": "Male",
    "hair_color": "Blond",
    "height": "172",
    "homeworld": "https://swapi.co/api/planets/1/",
    "mass": "77",
    "name": "Luke Skywalker",
    "skin_color": "Fair",
    "created": "2014-12-09T13:50:51.644000Z",
    "edited": "2014-12-10T13:52:43.172000Z",
    "species": [
        "https://swapi.co/api/species/1/"
    ],
    "starships": [
        "https://swapi.co/api/starships/12/",
        ...
    ],
    "url": "https://swapi.co/api/people/1/",
    "vehicles": [
        "https://swapi.co/api/vehicles/14/"
        ...
    ]
}

1 Ответ

0 голосов
/ 30 июня 2018

Вы находитесь на правильном пути и почти его получили. Species - это массив, поэтому вам понадобится еще один forkJoin, если существует более одного вида:

return this.http.get(characterUrl)
.pipe(
  mergeMap((character: any) => {
    return forkJoin(
      // Get the homeworld
      this.http.get(character.homeworld),
      // Another forkJoin for the species
      forkJoin(
        character.species.map(type => {
          return this.http.get(type)
        })
      )
    ).pipe(
      // Transform to a consumable object
      map(d => {
        return  {
          character: character,
          homeworld: d[0],
          species:   d[1]
        }
      })
    )
  })
)

В качестве примера возвращается объект со следующими свойствами:

character: Object
homeworld: Object
species: Array[1]

Вот демоверсия StackBlitz

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...