Last active
April 29, 2020 11:55
-
-
Save automaticalldramatic/b02848248577b820fd3e2184705029dc to your computer and use it in GitHub Desktop.
Gists for the post - https://rizwaniqbal.com/posts/paginating-firestore-collections-with-snapshot-listeners/
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// I updated the interface | |
export interface ObservablePaginatedResult { | |
cards: Observable<Array<SomeCards>>; | |
nextPage: IterableIterator<() => void>; // the method returned by iterator should be called to stop listening for changes on this page | |
} | |
public WatchPaginatedCards(pageSize: number = this.DefaultPageSize): <ObservablePaginatedQuery> { | |
const cards$: ReplaySubject<Array<SomeCards>> = new ReplaySubject<SomeCards[]>(1); | |
const next = this.paginator(cards$, pageSize); | |
return {cards: cards$.pipe(distinctUntilChanged()), nextPage: next}; | |
} | |
private* paginator(cardsQueue: Subject<Array<SomeCards>>, pageSize: number): IterableIterator<() => void> { | |
// create a query for Firestore | |
let query = this.cardsCollRef.orderBy('priority', 'desc').limit(pageSize); | |
let lastVisible = null; | |
while (lastVisible !== undefined) { | |
// create a snapshot query to get cards in descending priority | |
const stopListening = query.onSnapshot((documentSnapshots) => { | |
// Get the last visible document | |
lastVisible = documentSnapshots.docs[documentSnapshots.docs.length - 1]; | |
if (lastVisible === undefined) { | |
return; | |
} | |
// Update the query variable with a new query that starts after the last visible in the previous query | |
query = this.cardsCollRef | |
.orderBy('priority', 'desc').limit(pageSize) | |
.startAfter(lastVisible); | |
// use the same logic as SyncCards to push a card array into the subject | |
const cards: SomeCards[] = []; | |
cardSnapshot.forEach((cardDoc) => { | |
cards.push(cardDoc.data() as SomeCards); | |
}); | |
cardsQueue.next(cards); | |
}); | |
yield stopListening; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment