3d cartoon hands holding a phone

Unlock full course by purchasing a membership

Lesson 6

Adding Pagination with Infinite Scroll

Utilising HTTP request streams

STANDARD

Adding Pagination with Infinite Scroll

At the moment, we just get a bunch of GIFs, display them, and that’s it. We are going to improve this a little now. Instead of just dumping everything we get from a single request, we are going to only display a set amount of GIFs per “page”. When the user scrolls to the bottom of the page, we will automatically load in more GIFs if they are available.

To do this, we will need to make some changes to our getGifs() stream, and we are also going to make use of the ion-infinite-scroll component that Ionic provides for us.

Adding Infinite Scroll

Infinite scroll is one of the coolest Ionic components. The basic idea is that we can drop this into our ion-content area:

        <ion-infinite-scroll
          threshold="100px"
          (ionInfinite)="loadMore()"
        >
          <ion-infinite-scroll-content
            loadingSpinner="bubbles"
            loadingText="Fetching gifs..."
          >
          </ion-infinite-scroll-content>
        </ion-infinite-scroll>

Now, when the user is 100px from the bottom of the content area it will trigger the ionInfinite event whilst also displaying something to indicate that a load is happening. As you will soon see, we can also pass the ionInfinite event to our loading process so that when the load is complete we can tell the infinite scroll component to stop displaying the loading indicator.

Our implementation for this will involve using our gifs data in the template again. So, to avoid creating multiple subscriptions with the async pipe for the same data, we are going to switch to using the vm$ stream approach again.

Add the following stream as a class member to the HomeComponent:

  vm$ = combineLatest([this.gifs$.pipe(startWith([]))]).pipe(
    map(([gifs]) => ({
      gifs,
    }))
  );

This might look a bit unnecessary and silly, because it is. Using combineLatest is pointless here because we only have one stream at the moment, so we could just use gifs$ directly rather than creating a vm$ stream with combineLatest. However, just as we have with the other applications, we will be adding additional streams into this vm$ stream soon, so we are just setting it up this way now.

NOTE: Notice that we pipe the startWith operator onto our gifs$ stream. That is because getGifs will not immediately return a value - it needs to fetch data from an external API. Since combineLatest will only emit once all of its input observables have emitted a value, this will cause us problems. We are about to wrap our entire template in an *ngIf that will subscribe to this vm$ stream. If it hasn’t emitted yet, then our entire template will not be displayed until it does. By using startWith([]) our gifs$ stream will immediately emit an empty array as an initial value, and then once the data has loaded in from Reddit it will use the proper value. This way, our template can still display before the HTTP request has finished.

Modify the HomeComponent template to use the vm$ stream:

    <ng-container *ngIf="vm$ | async as vm">
      <ion-header>
        <ion-toolbar>
          <ion-title> Home </ion-title>
        </ion-toolbar>
      </ion-header>
      <ion-content>
        <app-gif-list
          *ngIf="vm.gifs"
          [gifs]="vm.gifs"
          (gifLoadStart)="setLoading($event)"
          (gifLoadComplete)="setLoadingComplete($event)"
        ></app-gif-list>
      </ion-content>
    </ng-container>

Now we can move on to implementing the infinite scroll.

Add the infinite scroll component inside of the content area:

        <app-gif-list
          *ngIf="vm.gifs"
          [gifs]="vm.gifs"
          (gifLoadStart)="setLoading($event)"
          (gifLoadComplete)="setLoadingComplete($event)"
        ></app-gif-list>

        <ion-infinite-scroll
          threshold="100px"
          (ionInfinite)="loadMore($event, vm.gifs)"
        >
          <ion-infinite-scroll-content
            loadingSpinner="bubbles"
            loadingText="Fetching gifs..."
          >
          </ion-infinite-scroll-content>
        </ion-infinite-scroll>
STANDARD
Key

Thanks for checking out the preview of this lesson!

You do not have the appropriate membership to view the full lesson. If you would like full access to this module you can view membership options (or log in if you are already have an appropriate membership).