question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Example for Server Side Pagination

See original GitHub issue

I’m struggling to implement server side pagination (standard paginated data table) using feathers-vuex. I currently bind the items of the data table to a computed property like this:

computed: {
  items () {
    // Return the items from the store
    return this.findGetterForItems()
  }
}

Next, I watch for changes in a pagination object (limit, skip, items per page). For each change, I clear the store by commiting clearAll and load the new data into the store using the find (from server) method.

Am I doing this correctly or is there a more “vuexish” way to do it? For questions like this, it would be nice to have a more “complete” example than the chat one…

Issue Analytics

  • State:closed
  • Created 6 years ago
  • Reactions:2
  • Comments:5 (2 by maintainers)

github_iconTop GitHub Comments

2reactions
ricardopolocommented, Jun 25, 2018

I am interested in this one too. What is the recommended way yo query a paginated service

1reaction
FossPrimecommented, Jun 28, 2019

Here is the OFFICIAL article on pagination… it’s a bit light, https://feathers-vuex.feathers-plus.com/service-module.html#querying-with-find-pagination

I’m very happy with the results of my implementation. However I need to throw it into a mixin or something to generalize it. Making a demo out of this would be fun

in my data I have

  data () {
    return {
      search: '',
      loading: false,
      scrapPagination: true
    }
  },

Then I check if a page is left.

    ...mapState('user', {
      paginationFull: `pagination`
    }),
    pagination () {
      return this.scrapPagination || this.paginationFull[NS]
    },
    isAPageLeft () {
      if (!this.paginationFull[NS] || this.scrapPagination) {
        return true
      }
      const loadedCount = this.paginationFull[NS].skip + this.paginationFull[NS].limit
      return loadedCount < this.paginationFull[NS].total
    }

Methods is where it gets nasty. One of the goals is to make the user mostly unaware of any loading occurring, as such I load two pages on every go. I use the 10th from last elements on screen presence as a trigger for loading more users. And I ignore pagination object if switching between regular listing and searching. Searching can be intense, so only do it if requested, as opposed to running the regex engine on everything for no reason.

methods: {
    ...mapActions('user', {
      findUsers: 'find'
    }),
    ...mapMutations('user', {
      clearAll: 'clearAll'
    }),
    onScroll () {
      const tolerance = 10
      if (!this.$refs.userEls || !this.isAPageLeft) {
        return
      }
      const triggerEl = this.$refs.userEls.length - tolerance > 0
        ? this.$refs.userEls[this.$refs.userEls.length - tolerance]
        : this.$refs.moreButton
      const that = this
      requestAnimationFrame(() => {
        if (isElementInViewport(triggerEl)) {
          that.loadMore()
        }
      })
    },
    async loadMore (bypass) {
      winston.debug(`${NS}: Loading More:`, this.pagination)
      if (
        bypass ||
        (this.isAPageLeft && !this.loading)
      ) {
        this.loading = true
        winston.debug(`${NS}: Loading More:`, 'FIRE!')
        const skip = this.scrapPagination ? 0 : this.pagination.skip + this.pagination.limit
        this.scrapPagination = false
        await this.findUsers({
          qid: NS,
          query: {
            $limit: LIMIT,
            $sort: SORT,
            $skip: skip,
            $search: this.search ? this.search : undefined
          }
        })
        // Load two pages to begin with
        if (this.isAPageLeft && !bypass) {
          this.loadMore(true)
        }
      }
      this.loading = false
    },
    reset () {
      this.scrapPagination = true
      this.clearAll()
    },
    init () {
      this.reset()
      this.loadMore()
    }
  },
  watch: {
    search: async function () {
      if (!this.search) {
        this.search = undefined
        this.init()
        return
      }
      this.init()
    }
  },
  created () {
    this.init()
    window.addEventListener('scroll', throttle(this.onScroll, 300))
  },
  destroyed () {
    window.removeEventListener('scroll', this.onScroll)
  }
}

I used faker for the dummy data.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Introduction to Client Side and Server Side Pagination in ...
Server -side pagination requests each page individually loaded upon navigation. The server needs to support pagination, and then the client-side ...
Read more >
Server-side pagination in Angular with ngx-pagination
Server -side pagination is a way of controlling a subset of data requests that were fetched from a client-side server, and are useful...
Read more >
How to Create a Server-Side Data Pagination Function in SQL ...
Pagination, also known as paging, is the process of dividing a document into discrete pages, … Server-side pagination is appropriate for large data...
Read more >
What exactly is server and client side pagination?
For example if you were displaying people by last name, the first page might be created by telling the server that you want...
Read more >
Server Side Pagination - Grid.js
Add server property to the pagination config to enable server-side pagination. Also, make sure the total property.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found