After countless attempts, I still haven't been able to figure it out. Any assistance would be greatly appreciated; I recently came across Angular and RxJs.
The issue I'm facing involves a service that fetches resources from various URLs of the swapi API. The problem is that I don't know in advance how many pages need to be fetched. To tackle this, I have been using concat
for each http.get(url)
call to create observables.
Currently, only the first page of data is being displayed in the component (i.e. firstPage
); all requests are being sent though.
export class PeoplesService {
urlSource = "https://swapi.co/api/people/";
pageResponse: GeneralResponse<People>;
fullResponse: Observable<GeneralResponse<People>>;
constructor(private _http:HttpClient) {
}
getPaged(n: number): string {
return this.urlSource + "?page=" + n;
}
fetch(): Observable<GeneralResponse<People>> {
let firstPage = this._http
.get<GeneralResponse<People>>(this.urlSource);
firstPage.subscribe(page => {
this.fullResponse = firstPage; // first page fetched
let pageToDownload = Math.ceil(page.count / page.results.length);
for(let i=2; i<=pageToDownload; i++) {
// Merge all observable (so all request) into one
concat(this.fullResponse,
this._http.get<GeneralResponse<People>>(this.getPaged(i)));
}
});
return this.fullResponse;
}
}
This is the basic code structure of my component:
ngOnInit() {
this.peoplesService.fetch().subscribe(r => this.movies = r.results);
// perhaps something like fetch().onNextFetch(this.movies.push(...r.results)) would work better here
// as every piece of data on all pages needs to be merged into this.movies
// or maybe we require a fetch().subscribeUntilCompleted(r => this.peoples = r.results)
}
I've been struggling to find an alternative to using subscribe - something that waits for the Observable to complete and collects all the returned values at once.
It seems like subscribe doesn't wait for the Observable's "onCompleted" status and doesn't get triggered each time to capture all the existing values. How can I fetch all the data?
Is there a way to make the Observable behave like a stream and direct it to this.peoples.push(...r.results)
? I'm not sure if I'm heading in the right direction with this approach.