Carlos Figueroa
Carlos Figueroa

Reputation: 37

How to make multiple http calls in the same function with Angular

What I want to achieve: Make calls from component.ts to the service this.getMatches, in this.getMatches I have to make some API calls and work with the data I get before it gets pushed to the array

What I did: 1: The function runs and send "gameId" as an argument to the function this.getmatches. I get an array of every match with all data that I pushed to every single match 2: I was able to find a method that worked after many tries, but it failed when it returning to the array

The problem: Sometimes it returns the same match, I noticed it happens when I add the "swtichmap" operator.

return

Services.ts

@Injectable({
  providedIn: 'root'
})
export class SummonerService {

  constructor( private http:HttpClient ) { }

  summonerName
  dataMatch
  matchParticipants
  matchHistory = [];

    getSummoner(summonerName,regionId){
    this.summonerName = summonerName
   return this.http.get(`http://localhost:3000/summName/${summonerName}/${regionId}` )
  };

   getMatches(gameId){
     return this.http.get( `http://localhost:3000/match/${gameId}` 
     ).pipe(
       tap( (data:any) => {
         console.log(data.match);
         this.dataMatch = data.match
         this.matchParticipants = data.match.participants
        }) ,
       switchMap( data => {
         return this.http.get(`http://ddragon.leagueoflegends.com/cdn/10.5.1/data/en_US/summoner.json`)
       }),
       tap( (data:any) =>{


         let spellsObj = data.data;
         const spellsArray:Array<any>[] = [];

         Object.keys(spellsObj).forEach( key =>{

           let spell = spellsObj[key]

           spellsArray.push(spell)
          });

          this.matchParticipants.forEach( participants => {

            let spellId1:any = spellsArray.find( (spell:any) => spell.key === JSON.stringify(participants.spell1Id) );
            let spellId2:any = spellsArray.find( (spell:any) => spell.key === JSON.stringify(participants.spell2Id) );


            let spellId1Image = `http://ddragon.leagueoflegends.com/cdn/10.5.1/img/spell/${spellId1.id}.png`
            let spellId2Image = `http://ddragon.leagueoflegends.com/cdn/10.5.1/img/spell/${spellId2.id}.png`

            participants.spellId1Info = spellId1
            participants.spellId2Info = spellId2

            participants.spellId1Info.image = spellId1Image
            participants.spellId2Info.image = spellId2Image
    });
       }),
       map ( data =>{ 
          return this.dataMatch
         })
       )};

I put part of the code, but I need to make more calls like this .

 switchMap( data => {
         return this.http.get(`http://x.json`)
       }),

I don't know if the call here with the "switchmap" was done correctly either

Component.ts

onSubmit( ){

    this.summ.getSummoner( this.summoner.name,this.summoner.regionId )
    .pipe( 
      tap( (summoner:any) => this.matchHistory = summoner.matchHistory ),
      concatMap( (summoner:any) => {
        const observables = this.matchHistory
        .map( element => this.summ.getMatches(element.gameId));
          return forkJoin(observables)
      }),
      map( (matchesArray:any) => {
        let gameIdArray = this.matchHistory.map( element => element.gameId)

        this.matchesArray = matchesArray.sort((a, b) => {  
          return gameIdArray.indexOf(a.gameId) - gameIdArray.indexOf(b.gameId);
        });
        return matchesArray
      })
      ) .subscribe();

Upvotes: 0

Views: 1021

Answers (1)

Jan-Niklas Wortmann
Jan-Niklas Wortmann

Reputation: 421

switchMap here looks pretty ok to me, if you are not sure about that, feel free to check out my blog post about this topic: https://dev.to/rxjs/about-switchmap-and-friends-2jmm.

If you want to make multiple requests you need to apply a combination operator within the switchMap, probably either merge or forkJoin. The code could look like this:

 switchMap( data => merge(
    this.http.get(`http://x.json`),
    this.http.get(`http://y.json`),
    this.http.get(`http://z.json`)
)),

So the question is which of those you want to use:

You want to use merge when you don't really care if the other HTTP calls are already completed. You will get a new value emited after the switchMap every time one of those HTTP requests return a response and you will also only get that very response.

You want to use forkJoin when you care that all HTTP calls are completed before you go one. You will also get an Array of HTTP responses which you can use to continue the processing.

Upvotes: 1

Related Questions