Reputation: 539
I am trying to call 3 different APIs before a component loads using the Resolve.
This code below is written inside the resolve function and is returning an object with all response packaged.
Now When The component loads, before I receive the response from server.. it returns null for each of the keys in the object returned.
Please help how do I solve this kinda issue. How do I stop it from returning until the response is not received from the API.
resolve() {
this._apiFactory.getA().subscribe(response => {
responseA = response;
});
this._apiFactory.getB().subscribe( response => {
responseB = response;
});
this._apiFactory.getC().subscribe( response => {
responseC = response;
});
return {
'A': responseA ,
'B': responseb ,
'C': responseC
};
}
Upvotes: 2
Views: 11710
Reputation: 12960
You were returning the before your subscriptions could get finished. Used Fork Join to wait until all your Get
requests are completed and then returning the result of the get requests in your required format..
Update
Since Rxjs 6.5.0, forkJoin also accepts an object as an argument.
// dummy Observables
const obsArg = {
A: of([1]).pipe(delay(1000)),
B: of([1, 2, 3]).pipe(delay(2000)),
C: of([1, 2, 3, 4]).pipe(delay(3000))
}
return forkJoin(obsArg)
I tried it in Angular 6
and I was able to do it like:
// dummy Observables
let a = of([1]).pipe(delay(1000));
let b = of([1, 2, 3]).pipe(delay(2000));
let c = of([1, 2, 3, 4]).pipe(delay(3000));
let join = forkJoin(a,b,c).pipe(map((allResponses) => {
return {
A: allResponses[0],
B: allResponses[1],
C: allResponses[2]
};
}));
return join;
So, I manipulated the data in forkJoin
and returned the forkJoin
itself. see it here: https://stackblitz.com/edit/angular-xepafp?file=src%2Fapp%2FAPIResolver.ts
In angular2, something like this should work:
resolve() {
return Observable.forkJoin(
this._apiFactory.getA(),
this._apiFactory.getB(),
this._apiFactory.getC()
).map((allResponses) => {
return {
A: allResponses[0],
B: allResponses[1],
C: allResponses[2]
};
})
}
Upvotes: 6
Reputation: 189
Please Don't use Subscribe instead you can return your observables as
let a= observable(1);
let b= observable(2);
let c= observable(3);
return forkJoin(a,b,c);
this will help you
Upvotes: 0
Reputation: 6306
As of RxJS 6.5+ the way to do it is:
return forkJoin({
todos: timer(500).pipe(mapTo([{ title: 'forkJoin'}])),
user: timer(500).pipe(mapTo({ id: 1 }))
});
Upvotes: 3
Reputation: 7765
This can be done with combineLatest
as well. See this stackblitz
import { Injectable } from "@angular/core";
import { Resolve, ActivatedRouteSnapshot } from "@angular/router";
import { of, combineLatest } from "rxjs";
import { delay } from "rxjs/operators";
@Injectable({
providedIn: "root"
})
export class TestResolver implements Resolve<any> {
constructor() {}
resolve(route: ActivatedRouteSnapshot) {
let a = of([1]).pipe(delay(1000));
let b = of([1, 2, 3]).pipe(delay(2000));
let c = of([1, 2, 3, 4]).pipe(delay(3000));
return combineLatest(a, b, c);
}
}
Upvotes: 0