Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Pagination #47

Open
michan85 opened this issue Nov 5, 2018 · 5 comments
Open

Feature: Pagination #47

michan85 opened this issue Nov 5, 2018 · 5 comments

Comments

@michan85
Copy link

michan85 commented Nov 5, 2018

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

@IjzerenHein
Copy link
Owner

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

@IjzerenHein IjzerenHein changed the title Paging Feature: Pagination Nov 20, 2018
@agrublev
Copy link

agrublev commented Feb 6, 2019

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()
}

@MarcDAFrame
Copy link

any update on this feature?

@IjzerenHein
Copy link
Owner

Unfortunately no. Any PRs in this space are welcome though.

@robclouth
Copy link

robclouth commented Dec 8, 2020

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?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants