Reputation: 311
I have a function which makes two http calls, the input of second http depends first http response and I need the two results to be returned at the same time. I have the below code which throws the error
SomeMethod(): Observable<any> {
let firstResult;
let secondResult;
firstResult = http.get('////').map(data => {
console.log('first response')
secondResult = http.get('//// + {data.UserId}').map(response => {
console.log('second response')
})
})
return forkJoin([firstResult, secondResult]);
}
CallingMethod() {
this.SomeMethod.subscribe(([firstResult, secondResult]) =>{
/// Some logic
})}
Getting error as undefined. Expected a observable, promise or array. After debugging got to know that first console output is printing, the second http call is never made and response is never seen.
How to return two nested calls responses together using forkJoin or any other mechanism?
Upvotes: 2
Views: 7773
Reputation: 4816
Here is a StackBlitz of how to do this using concatMap
. concatMap
will execute sequentially, where as forkJoin
will execute in parallel.
What you need to know
const requests = [
this.http.get('https://jsonplaceholder.typicode.com/todos/1'),
this.http.get('https://jsonplaceholder.typicode.com/todos/2'),
this.http.get('https://jsonplaceholder.typicode.com/todos/3'),
this.http.get('https://jsonplaceholder.typicode.com/todos/4'),
this.http.get('https://jsonplaceholder.typicode.com/todos/5'),
this.http.get('https://jsonplaceholder.typicode.com/todos/6')
];
from(requests).pipe(
concatMap((request) => request.pipe(delay(2200)))
).subscribe((res) => {
this.results$.next(this.results$.getValue().concat(res))
})
from
operator to take your array and emit each array itemconcatMap
I added a delay here as well to simulate slow loading.
Upvotes: 6
Reputation: 508
Use Async & await to control multiple http requests.
async SomeMethod(): Promise <any> {
let firstResult;
let secondResult;
firstResult = await http.get('////').toPromise();
secondResult = await http.get('//// + {res1.UserId}').toPromise();
return forkJoin(firstResult, secondResult);
}
CallingMethod() {
this.SomeMethod().then(result => {
/// Some logic
});
}
Upvotes: 3
Reputation: 9880
forkJoin
takes arguments inline, not as an array (unless that's a change in rxjs between latest and what was bundled in Angular v4)
const req1 = this.http.get('https://jsonplaceholder.typicode.com/todos/1');
const req2 = this.http.get('https://jsonplaceholder.typicode.com/todos/2');
const results = forkJoin(req1, req2)
Output:
[
{
"userId": 1,
"id": 1,
"title": "delectus aut autem",
"completed": false
},
{
"userId": 1,
"id": 2,
"title": "quis ut nam facilis et officia qui",
"completed": false
}
]
StackBlitz is in v6 but its easy enough to back track if needed.
Upvotes: 0
Reputation: 3162
The following code should work:
SomeMethod(): Observable < any > {
let firstResult;
let secondResult;
return http.get('////').pipe(
switchMap(res1 => http.get('//// + {res1.UserId}').pipe(
map(res2 => [res1, res2])
))
);
}
CallingMethod() {
this.SomeMethod().subscribe(([firstResult, secondResult]) => {
/// Some logic
})
}
Upvotes: 1