I am working on a component that requires fetching data from multiple endpoints through independent API calls. I want to make all these calls simultaneously and only load the user interface once all the data has been fetched successfully.
My approach involves using forkJoin in RxJS, but as someone new to this library, I'm not completely confident that I'm implementing it correctly. Below is an example of my code. I would appreciate any assistance or guidance.
import { Component, Input, OnInit, ElementRef, ViewChild } from '@angular/core';
import { Observable, forkJoin, of } from 'rxjs';
import { flatMap } from 'rxjs/operators';
import { DataService, ItemGroupDto} from 'src/app/shared/services/data-service.service';
import { UserService} from 'src/app/shared/services/user-service.service';
@Component({
selector: 'app-sample',
templateUrl: './sample.component.html',
styleUrls: ['./sample.component.less']
})
export class SampleComponent implements OnInit {
@Input() itemGroupId: number;
public datasetOne: Observable<any[]>;
public datasetTwo: Observable<any[]>;
public currentApprover: string;
constructor(
private _dateService: DateService,
private _userService: UserService,
) {}
ngOnInit() {
this.getData();
}
private _getApprover(itemGroupId: number) : Observable<ItemGroupDto> {
const approver = this._userService.getApprover(itemGroupId);
approver.subscribe(results => {
const approver = results.approvers.find(approver => (
approver.Id === 1
));
this.currentApprover = approver.UserFullName;
})
return approver;
}
private _sampleDatasetOne() : Observable<any>{
const sampleDatasetOne = this._dataService.sampleDatasetOne();
sampleDatasetOne.subscribe(results => {
this.datasetOne = results;
})
return sampleDatasetOne;
}
private _sampleDatasetTwo() : Observable<any>{
const sampleDatasetTwo = this._dataService.sampleDatasetTwo();
sampleDatasetTwo.subscribe(results => {
this.datasetTwo = results;
})
return sampleDatasetTwo;
}
getData() {
let sampleDatasetOne = this._sampleDatasetTwo();
let sampleDatasetTwo = this._sampleDatasetTwo();
let approver = this._getApprover(this.itemGroupId);
forkJoin(sampleDatasetOne, sampleDatasetTwo, approver).subscribe(_ => {
// all observables have been completed
this.loaded = true;
});
}
}
This implementation is inspired by a tutorial I came across while researching how to use forkJoin for this specific purpose. It meets my requirements perfectly as it allows me to process the results for each API call within their respective subscriptions and then display the data in the view using *ngIf or equivalent when all calls are complete.
However, an alternative approach that I frequently encounter in online tutorials is the following:
let sampleDatasetOne = this._dataService.sampleDatasetOne();
let sampleDatasetTwo = this._dataService.sampleDatasetTwo();
let approver = this._userService.getApprover(this.itemGroupId);
forkJoin([sampleDatasetOne, sampleDatasetTwo, approver]).subscribe(results => {
this.datasetOne = results[0];
this.datasetTwo = results[1];
const approver = results[2].approvers.find(approver => (
approver.Id === 1
));
this.currentApprover = approver.UserFullName;
});
Although this approach seems complex and harder to interpret, I see it being used often. Am I missing something fundamental or is there a key concept I am overlooking?
In essence, I am seeking the most efficient Angular/RxJS solution for handling multiple API calls simultaneously and processing the results accordingly.
If I am on the right track, any feedback on potential improvements or corrections to my current implementation would be highly valuable. Thank you for any assistance in unraveling this for me.