2

Problem: I want to get data from the Star Wars Api(SWAPI). I want to make an initial http call, and then in that same call, get values from 2 additional api calls. Swapi returns a json object, but its values are also urls to other parts of their api.

Currently, this code works, but I'm only able to retrieve the character object, and then the homeworld object.

Here is my code:

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))

  }

This is the code I'm trying to refactor from:

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 example json object:

{
    "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 Answer 1

3

You are on the right track there and almost had it. Species is an array, so you would need another forkJoin in there as well in case there is more than one species type:

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]
        }
      })
    )
  })
)

As an example, this will return an object with the following properties:

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

Here is a StackBlitz demo

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.