You have unlimited access as a PRO member
You are receiving a free preview of 3 lessons
Your free preview as expired - please upgrade to PRO
Contents
Recent Posts
- Object Oriented Programming With TypeScript
- Angular Elements Advanced Techniques
- TypeScript - the Basics
- The Real State of JavaScript 2018
- Cloud Scheduler for Firebase Functions
- Testing Firestore Security Rules With the Emulator
- How to Use Git and Github
- Infinite Virtual Scroll With the Angular CDK
- Build a Group Chat With Firestore
- Async Await Pro Tips
Infinite Scroll in Angular With Firebase Data
Episode 37 written by Jeff DelaneyWhen you have a large collection of information in your database, it’s often not practical to query it in a single go. We could implement pagination, but that usually doesn’t deliver a great user experience for modern progressive web apps. A better approach is to use the scroll position of the user to query the next batch of data, aka infinite scroll.
In this lesson, I am going to show you how to asynchronously combine multiple array Observables from AngularFire2, then display them in a component based on the user’s scroll position.
Adding the ngx-infinite-scroll Package
Keeping track of the scroll position of a user is no joke - that’s why we’re going to use the excellent ngx-infinite-scroll package. This gives us a reliable way to listen for scroll events, while also throttling the frequency of events to prevent making millions of unnecessary queries to Firebase.
npm install ngx-infinite-scroll --save |
Then add it your AppModule (or any module that is using it).
/// ...omitted |
Retrieving Data from Firebase
Our service will be responsible for querying data with AngularFire2. For this demo, I have a collection of eight movies, which will be loaded in batches of two.
Database Structure
Our database structure is about as simple as it gets.
movies |
movie.service.ts
ng g service movie |
When we query a FirebaseListObservable
we get an array of objects. In order to know where to start this query, we need the key from the previous batch of movies. Therefore, our service function will accept an argument for the previous key, allowing us to offset the query using the startAt
property.
import { Injectable } from '@angular/core'; |
Implementing Infinite Scroll Component
ng g component movies-list |
movies-list.component.html
Let’s start in the HTML of the component. Directly after our collection of movies, we add the infiniteScroll
directive provided by ngx-infinite-scroll. We set the throttle to 1000, which means the event will only fire ever 1000ms (1 second). This is important because we would could hypothetically send thousands of queries to Firebase in just a few seconds of scrolling. We also add a conditional loading spinner that will appear as long as there are still records left to retrieve in the database.
<h1>Movies</h1> |
movies-list.component.ts
This implementation pulls new data from firebase one query at a time and saves the returned values into a BehaviorSubject
. It works in the following logical steps
- Retrieve initial movies from the database during
ngOnInit()
- Grab 1 extra record and save its key
- When scroll event fires, grab another batch of movies offset by the
lastKey
. - When lastKey equals last movie in a new batch, we have reached the end of the database.
import { Component, OnInit} from '@angular/core'; |
Final Thoughts
You could improve on this implementation with an Angular list animation to stagger the appearance of new items as they are retrieved from the database.
Also, keep in mind that you lose the realtime connection to Firebase by creating your own BehaviorSubject
. This is probably not an issue for most infinite scroll situations, but something to keep in mind.
That’s it infinite scroll. Let me know what you think in Slack or in the comments below.