0

I'm getting data from APIs like this:

this.myService.getFirstData(slug).pipe(takeUntil(this.unsubscribe))
      .subscribe(firstData => {
        this.data = firstData;
        for (const column of this.data.columns) {
          if(column.Type == 'List'){
            // Another API call here for this type of data. Note: I need to link them for populating a form (like => firstData[0] : dataFromSecondApiCall)
           }else if(column.Type == 'Enum')
            {
             // Another API call here for this type of data
            }
            And so on...
         }
       });

I already performed these API calls and get my data, but I wanted a more efficient way(maybe with forkJoin ?) to do this since I need all the two API data for populating a form.

2
  • If data is not paginated better to make it a single api. The if condition that you wrote if checked in backend it will make things more easier. Single form single api call. Commented Jul 2, 2022 at 5:21
  • @KrishnadasPC They are Commented Jul 2, 2022 at 5:23

1 Answer 1

1

If I understand the problem right, this is the way I would implement this requirement. The comments try to explain the code.

this.myService.getFirstData(slug).pipe(
  // after getFirstData returns you can concatenate another series of http 
  // calls using the concatMap operator
  concatMap(firstData => {
     this.data = firstData;
     // we create an array to store the Observables that represent the
     // next calls we want to make
     let nextCalls Observable<any> = []
     for (const column of this.data.columns) {
       if(column.Type == 'List'){
         // depending on the type of column we push into the array a different
         // type of http request in the form of an Observable
         nextCalls.push(buildNextCallForList())
       } else if (column.Type == 'Enum') {
         nextCalls.push(buildNextCallForEnum())
       }
     }
     // eventually we exit concatMap returning the Observable returned by forkJoin
     // forkJoin will execute all the next http calls concurrently
     // and return an array with all the responses received
     return forkJoin(nextCalls)
  }),
  tap(dataFromSecondCalls => {
    // here you need to find if there is a way to link the results obtained
    // by the next calls with the data retrieved with the first call
    // and with what you want to achieve as final result
  })
)
// you can now subscribe
subscribe()

I have not tried this code myself, so there may be syntactical errors, but I hope the spirit of the code is clear.

Consider that you probably do not need the takeUntil operator since this seems to be an http call and http calls produce a stream that notifies only 1 value (or errors) and complete immediately afterwords. So there is no need to unsubscribe it with takeUntil.

You may find some inspiration about how to use Observables in http scenarios looking at this article.

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

3 Comments

@Drenai concatMap is an operator that can be piped in any stream transformation. It is often used to concatenate http calls. Can you explain in more details your comment?
@Drenai there is no difference between "multiple sequential emits" and "just one emit". You may have to concat that one emit with a following Observable. This is the standard practice when you have to call an http service and, based on the results returned, call a subsequent http service. In order to be able to do this sequential series of calls you either use concatMap or swichMap. The first is the default choice, the second is the choice when you want to kill in-fly requests when upstream notifies a new value. You may find the article I have linked in the response interesting.
@Drenai let me ask you something. How would you implement the following scenario. You have to call httpServiceOne, receive the answer and then call httpServiceTwo with data received from the first call as parameters of the second call?

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.