简体   繁体   中英

Angular - Avoid nested subscription of IntersectionObserver

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>&nbsp;</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:

  1. A value from the intersection observer is fired
  2. Debounce operator will filter the value if the intersection observer is firing it rapidly ( Totally optional, remove this if it does not fit your use case)
  3. Concatmap operator returns a new observable of the movies to which you can subscribe now

NOTE: There is also switchMap and mergeMap the you can use that fit your use case

See: mergeMap

SwitchMap

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM