I've been looking for a solution all over the web, but couldn't find anything that fits my user case. I'm using the MEAN stack (Angular 6) and I have a registration form. I'm looking for a way to execute multiple HTTP calls to the API and each one is dependent on the returned result from the previous one. I need something that looks like this:
firstPOSTCallToAPI('url', data).pipe(
result1 => secondPOSTCallToAPI('url', result1)
result2 => thirdPOSTCallToAPI('url', result2)
result3 => fourthPOSTCallToAPI('url', result3)
....
).subscribe(
success => { /* display success msg */ },
errorData => { /* display error msg */ }
);
What combination of RxJS operators do I need to use to achieve this? One possible solution would be to nest multiple subscriptions, but I want to avoid that and do it better with RxJS. Also need to think about error handling.
For calls that depend on previous result you should use concatMap
firstPOSTCallToAPI('url', data).pipe(
concatMap(result1 => secondPOSTCallToAPI('url', result1))
concatMap( result2 => thirdPOSTCallToAPI('url', result2))
concatMap(result3 => fourthPOSTCallToAPI('url', result3))
....
).subscribe(
success => { /* display success msg */ },
errorData => { /* display error msg */ }
);
if your async method does not depend on return value of the precedent async call you can use
concat(method(),method2(),method3()).subscribe(console.log)
Try this , Angular provides feature to call multiple API at a time.
forkJoin()
You will get data in array
as in same sequence which you call API.
Ex:
forkJoin(request1, request2)
.subscribe(([response1, response2]) => {
You can find more read
I have also given another answer. Please check this, it may also helps you.
import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/forkJoin';
@Injectable()
export class DataService {
constructor(private http: HttpClient) { }
public requestDataFromMultipleSources(): Observable<any[]> {
let response1 = this.http.get(requestUrl1);
let response2 = this.http.get(requestUrl2);
let response3 = this.http.get(requestUrl3);
return Observable.forkJoin([response1, response2, response3]);
}
}
The above example shows making three http calls, but in a similar way you can request as many http calls as required
import { Component, OnInit } from '@angular/core';
import { DataService } from "../data.service";
@Component({
selector: 'app-page',
templateUrl: './page.component.html',
styleUrls: ['./page.component.css']
})
export class DemoComponent implements OnInit {
public responseData1: any;
public responseData2: any;
public responseData3: any;
constructor(private dataService: DataService) {}
ngOnInit() {
this.dataService.requestDataFromMultipleSources().subscribe(responseList => {
this.responseData1 = responseList[0];
this.responseData2 = responseList[1];
this.responseData3 = responseList[1];
});
}
}
Let me show you how to here, assuming I have much of emails I want to deliver an email to sequentially:
sendEmails() {
this.isLoading = true;
const calls = this.emails <<-- assume this contain an array of emails
.map(email => this.userEmailService.deliver({email: email, userId: 1242}));
from(calls) <<-- make use of the from.
.pipe(
concatMap(res => res),
finalize(() => this.isLoading = false)
).subscribe(() => { });
}
I hope this helps.