2

I have to make multiple API calls(http-requests) to get all the data I need.

Since I have to make 2 independent API calls that both should be finished with retrieving data, I am trying to sync to that.

I have nearly 0 experience in typescript/angular and couldn't find a solution via google.

Here are the API calls I'm making(signatures):

public supportedLanguages(observe?: 'body', reportProgress?: boolean): Observable<Array<string>>;
public getAllFilters(acceptLanguage?: string, observe?: 'body', reportProgress?: boolean): Observable<Array<Filter>>;

Here is the code I am currently using to fill Array<Type>:

this.langService.supportedLanguages().subscribe(langs => setTimeout(() =>
  this.langs.push(...langs), 1000));
this.categorieService.getAllFilters('de').subscribe(categories => setTimeout(() => {
  this.categories.push(...categories), 1000));

I am guessing that this is not the right approach to retrieving the data, but I haven't found a better way(I am very new to typescript/angular).

What are the right steps to take to wait for said data to be loaded?

5 Answers 5

4

You can use

(I am using "rxjs": "^5.5.11").

forkJoin

import 'rxjs/add/observable/forkJoin';
import { Observable } from 'rxjs';
import { Subscription } from 'rxjs/Subscription';


/* Multiple Service calls are asynchronism. use forkJoin to group service calls */  
Observable.forkJoin(
  this.supportedLanguages();
  this.getAllFilters()
).subscribe(
    response =>{
      //response[0] is data returned by API supportedLanguages
      //response[1] is data returned by API getAllFilters
    }
    error => console.log("Error: ", error),
    () =>{
      //All the API calls are completed here. Put your code here
      //codes should be executed after the completion of all API calls
    }
)
Sign up to request clarification or add additional context in comments.

1 Comment

Observable.forkJoin (RxJS 5) changes to just forkJoin() in RxJS 6
1

you can try forkJoin from rxjs:

forkJoin(
    this.langService.supportedLanguages(),
    this.categorieService.getAllFilters('de'))
)
.subscribe([langs, categories]=>{
  ...
})

Comments

1

You could also just use a combination of async, await and promises.
First you'd have to append .toPromise() to your service methods. Then in your component.ts file add the following method...

private async fetchData() {
  return await Promise.all([
    this.langService.supportedLanguages();
    this.categoryService.getAllFilters();
  ]).then(res => {
    this.langs.push(res[0]);   //res[0] is data returned by API supportedLanguages
    this.categories.push(res[1]); //res[1] is data returned by API getAllFilters
    this.status = true; // Confirms that now you have all your data back
  }
}

Call this.fetchData() inside ngOnInit()

Then maybe you'd have a status variable that you'd initialize to false and then set to true once all the data has been returned.

2 Comments

This is so simple. Nice.
Prefer 'rxjs' observables over Promises in Angular angular.io/guide/comparing-observables
0

You can use ForkJoin from Rxjs 6:

import {forkJoin} from 'rxjs';

// ...

forkJoin(
    this.langService.supportedLanguages(),
    this.categorieService.getAllFilters('de'))
).subscribe([langs, categories] => {
  // ...
})

OR, you can put the 2 API calls in a Promise:

function recoverData() {
    return new Promise((resolve, reject) => {
        this.langService.supportedLanguages().subscribe(langs => this.langs.push(...langs), 1000);
        this.categorieService.getAllFilters('de').subscribe(categories => this.categories.push(...categories), 1000);

        resolve();
    });
}

And then you use it like that:

recoverData().then(() => {
    // Some code
});

Comments

0

If you want call the API in same times and return in same times, you could use ForkJoin from rxjs, see about the documentation

forkJoin(
    this.langService.supportedLanguages(),
    this.categorieService.getAllFilters('de'))
).subscribe(x => 
console.log(x[0]); //result from api call 1
console.log(x[1]); //result from api call 2
 )

but if you want call first api, then after first api finish, you want call the second api. you could use concatMap, see about documentation here, concat map used maybe when your second api, need parameter from first

this.langService.supportedLanguages().pipe( 
 concatMap(resultFromApi1 => this.categorieService.getAllFilters('de'))
).subscribe(x => console.log(x)) //x = result from api 2;

I have nearly 0 experience in typescript/angular and couldn't find a solution via google.

you must try different way, cause angular not only angular. like 'rxjs' and other.. you need know what library js you used. and carefully with version, cause the angular really - really confusing about version and have different because the structure writing is a little different

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.