Robert
Robert

Reputation: 564

Subscribe to multiple async http calls

on ngOnInit i make 4 http request for data, after that i need to load the data from server to fill the forms with the data based on data model of last 4 http call.

In short words i need to subscribe to this 4 http calls, and make sure don't fail if they don't fail finally i can call the 5th http call to get data from server.

From what i understand, i should avoid to inest a observable and go with switch, but how to do this with 4 http call? should i create an observable wait for the http calls and if succed to use switchmap on the 5th http call?

This is the code.

      ngOnInit() {
    this.service.getProvince().subscribe(
        (value) => { return value; },
        (error: AppError) => {
            if (error instanceof NotFoundError) {
                console.log('Error richiesta http');
            } else {
                console.log(error);
            }
        });


    this.service.getLingueStraniere().subscribe(
        (value) => { return value; },
        (error: AppError) => {
            if (error instanceof NotFoundError) {
                console.log('Error richiesta http');
            } else {
                console.log(error);
            }
        });

    this.service.getTitoliPreferenziali().subscribe(
        (value) => { return value; },
        (error: AppError) => {
            if (error instanceof NotFoundError) {
                console.log('Error richiesta http');
            } else {
                console.log(error);
            }
        });

    this.service.getRiserve().subscribe(
        (value) => { return value; },
        (error: AppError) => {
            if (error instanceof NotFoundError) {
                console.log('Error richiesta http');
            } else {
                console.log(error);
            }
        });
}


// this is the 5th call that need to be done only if last 4 call not fail

finalCall {
    this.service.getDomanda().subscribe((domanda: any) => {
        this.popolaForm(domanda); // Method that use data to fill foms
    },
        (error: AppError) => {
            if (error instanceof NotFoundError) {
                console.log('Error richiesta http');
            } else {
                console.log(error);
            }
        });
} 

Upvotes: 2

Views: 6829

Answers (3)

wentjun
wentjun

Reputation: 42586

You can make use of forkJoin. It waits for all observables to be completed, before emitting the last emitted value from each request. forkJoin throws an error if any of the observables throws an error.

let callOne = this.service.getLingueStraniere();
let callTwo = this.service.getTitoliPreferenziali();
 .
 .
 .
forkJoin([callOne, callTwo]).subscribe(response => {
  //handle success response
}, (error) => {
    // error handling
}, () => {
    // when observable is completed
});

You may read more about forkJoin over here.

Upvotes: 1

Anto Antony
Anto Antony

Reputation: 872

You can use forkJoin to combine all the requests and get the results as callback when all the requests are completed.

import { forkJoin } from 'rxjs';
import { switchMap } from 'rxjs/operators';

ngOnInit() {
 forkJoin([this.service.getProvince(),this.service.getLingueStraniere(),this.service.getTitoliPreferenziali(), this.service.getRiserve()])
     .pipe(switchMap(result => { 
          console.log('Province', result[0]);
          console.log('LingueStraniere', result[1]);
          console.log('TitoliPreferenziali', result[2]);
          console.log('Riserve', result[3]);
          return this.service.getDomanda();
      }))
      .subscribe((domanda: any) => {
         console.log('getDomanda', domanda);
       });                                                          
}

Upvotes: 2

kimy82
kimy82

Reputation: 4495

I would transform those subscriptions to promises using .toPromise() so you can wait for all 4 http requests to be completed and then fill the form. It is not a fully running example but the idea is said.

try {
    ... await this.service.getProvince().toPromise();
    ... await this.service.getTitoliPreferenziali().toPromise();
    ... await this.service.getLingueStraniere().toPromise();
    ... await this.service.getRiserve().toPromise();
    //fill form
}catch(error) {
 //show error message or do something like retry calls
}

Upvotes: -1

Related Questions