I'm currently working on an infinite scroll data list where the data is loaded incrementally each time the host element is visible (invisible div at the end of each set of data).
I am however having trouble managing the subscriptions. I want to make the request and push more data into the array when the element is intersected.
I know nested subscriptions are an anti-pattern, so how can I get around this?
Here is the template and the logic:
<tbody>
<tr *ngFor='let movie of movieList; trackBy:trackByMovieId' (click)="selectMovie(movie.id)">
...
</tr>
<div *ngIf="!isOneFilterActive()" #sentinel> </div>
</tbody>
...
...
...
ngAfterViewInit(): void {
this.intersectionObserver.createAndObserve(this.sentinel).pipe(
filter((isVisible: boolean) => isVisible)).subscribe(() => {
// end of list detected: request more data
this.apiManager.fetchMovies().subscribe(movieList => {
if (movieList) {
this.movieList.push(...movieList.content);
}
});
}
);
}
You can simply use a pipe operator to simplify the code like this
this.intersectionObserver.createAndObserve(this.sentinel)
.pipe(
filter((isVisible: boolean) => isVisible),
debounce(1000),
concatMap(x => this.apiManager.fetchMovies())
).subscribe(movieList => {
if (movieList) {
this.movieList.push(...movieList.content);
}
}
);
FLOW:
NOTE: There is also switchMap and mergeMap the you can use that fit your use case
See: mergeMap