I have multiple http posts that fetches JSON data from a MySQL database. I want a function to listen to all of them and run the next piece of code once all of them returned that data has been received.
I've tried multiple variations of async with await, but the function doesn't appear to wait for the HTTP post to finish.
I've got a risk service risk.service.ts to get the riskTable for instance:
getRiskTable(): Observable<Risk[]> {
return this.http.get(`${this.baseUrl}/getRiskTable`).pipe(
map((res) => {
this.riskTable = res['data'];
return this.riskTable;
}),
catchError(this.handleError));
}
On my Dashboard I call this code:
getRiskTable():any {
return this.riskService.getRiskTable().subscribe(
(res: []) => {
this.riskTable = res; // the value is correctly captured here
return true;
},
(err) => {
this.error = err;
}
);
}
And then an async function that runs multiple of these functions, in theory it's suppose to wait until all the functions complete and then log the value. But for some reason the global variable this.riskTable is undefined in this function.
async getAllData(){
let riskTable = await this.getRiskTable();
let risks = await this.getAllRisks();
console.log(riskTable); //This returns stuff
console.log(risks);
console.log(this.riskTable); //This returns undefined even though it was set in getRiskTable
}
Please any pointers - I am very new to angular and the complexity of this has me completely stumped. 2 Days and 100x variations to get this to work I am slowly losing my bananas!
First off the async
/await
keywords are for use with promises, not Observable
s. So you can convert an observable to a promise using toPromise()
or you can use rxjs ForkJoin. You also need to change the methods to return either an observable or return a promise, you can't do much with Subscription which is what subscribe
returns when you call it and that is what you are passing now from getRiskTable
.
One other issue is that you are not taking advantage of the type system, do not use any
everywhere because these errors could have been caught at transpile time and now you have to guess why it's failing at run time which is more difficult.
import { forkJoin } from 'rxjs';
import { shareReplay } from 'rxjs/operators';
getRiskTable() : Observable<Risk[]> {
const tableObservable = this.riskService.getRiskTable().pipe(shareReplay());
tableObservable.subscribe((res) => this.riskTable = res, (err) => {this.error = err;});
return tableObservable;
}
getAllData() {
let riskTable = this.getRiskTable();
let risks = this.getAllRisks(); // should also return some observable
forkJoin(riskTable, risks).subscribe(_ => {
// all observables have been completed
});
}
Note that I also added shareReplay
which ensures that multiple subscriptions to the same observable do not result in multiple calls to your API end point. One result is shared between multiple subscriptions to the observable.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments