Open michan85 opened 6 years ago
Hi, Pagination is still on my radar, but haven't found an elegant solution yet that I like. I hope to address this in the following weeks. If you have a definitive solution/API in mind, please share it here. Cheers and thanks for the feedback
I have a proposed api. If a timestamp is required then you can use this type of code:
// loadNext function of Collection class
Firebase.firestore
.collection("SOME_COLLECTION")
.where("timestamp", "<", LAST_SHOWN_ITEM.timestamp)
.orderBy("timestamp", "desc")
.limit(LIMIT_OF_QUERY)
Then in firestore code something like
// Inside store
const todos = new Collection("todos", {
DocumentClass: Todo
});
todos.query = (ref) => ref.orderBy('created', 'asc').limit(3);
// Inside app js
onClickNext = () =>{
todos.loadNext()
}
any update on this feature?
Unfortunately no. Any PRs in this space are welcome though.
This is what I'm using:
import { Collection, Document } from "firestorter";
import { CollectionSource, ICollectionOptions } from "firestorter/lib/Types";
import flatten from "lodash/flatten";
import uniqBy from "lodash/uniqBy";
import { computed, observable } from "mobx";
export default class PagedCollection<T extends Document> {
@observable private collections: Collection<T>[] = [];
@observable private source: CollectionSource;
@observable private options: ICollectionOptions<T>;
@observable isLoadingMore = false;
constructor(source: CollectionSource, options: ICollectionOptions<T>) {
this.options = options;
this.source = source;
const collection = new Collection<T>(this.source, this.options);
this.collections.push(collection);
}
@computed get docs() {
return uniqBy(flatten(this.collections.map(c => c.docs.map(d => d))), "id");
}
@computed get isFirstPageLoading() {
return this.collections[0].isLoading;
}
async loadMore() {
const prevCollection = this.collections[this.collections.length - 1];
const newCollection = new Collection<T>(this.source, this.options);
const lastDoc = prevCollection.docs[prevCollection.docs.length - 1];
newCollection.query = prevCollection.queryRef.startAfter(lastDoc.snapshot);
newCollection.mode = "off" as any;
this.isLoadingMore = true;
await newCollection.fetch();
this.isLoadingMore = false;
if (newCollection.hasDocs) {
newCollection.mode = "auto" as any;
this.collections.push(newCollection);
}
}
}
You define the page size with the limit in the initial query like this:
this.pagedCollection = new PagedCollection("pagedCollection", {
query: (ref: CollectionQuery) => ref.orderBy("createdAt", "asc").limit(10)
});
It seems to work. @IjzerenHein can you see any potential issues?
I created a PagedCollection class that extends Collection. ill be the first to admit its not great but i needed it quickly and maybe it can be useful to others.
Firestore paging is, to say the least limited, I could not seem to find a way to page backwards (endAt is not sufficient).
The basic premise is: keep a list of query objects nextPage queries.push prevPage queries.pop.
the limitations are: queries must be a function ( ref=>ref.where.... )
The code is here https://stackblitz.com/edit/react-firestore-todo-app-er1x8b?file=PagedCollection.js