Q-Table Server-Side Pagination Sync



  • Dear Quasar Gurus,

    I’ve studied the Synchronizing with server example. So far, my data populates the table as one giant data dump (over 50,000 rows). This causes the page to freeze for a long time until all the data is loaded. Of course, the way to fix this is to sync the Q-Table pagination logic with some server-side pagination logic, but I’m not quite sure how to do this.

    The official Q-Table example with the simulated server logic doesn’t really illustrate the full cycle between server and client. It would be really great if there was a real-world example in Python, PHP or Go that showed how the server-side pagination logic mirrors and feeds the client-side Q-Table pagination logic.

    I’ve already written a basic server-side REST API in Go for this app. (Not public yet.) I think I need to create a server-side endpoint that limits the returned results to e.g. 100 rows per page. (I have used this example to create my server-side pagination logic.)

    I think I’m very close to understanding this, but there’s still a gap in my understanding that I hope somebody can help me resolve. If nobody has a full server-to-client example to share, then I’ll ask a few questions:

    From the Q-Table sync example, there is the following:
    this.pagination.page = page

    Assuming the following . . .

    . . . can somebody explain when I would update the page object and what the logic would be based on?

    Can somebody show me an example of how the filter prop would work in this example? (It seems like the pagination props are enough. That’s why I’m not sure what filter is for.)

    For more background, this is the code I have so far:

    <template>
    <div>
    <q-table
          title="Available Accounts"
          :data="accountTable"
          :columns="accountTableColumns"
          :visible-columns="visibleTableColumns"
          table-class=""
          row-key="AccountID"
          dense
          wrap-cells
          separator="cell"
          :pagination.sync="pagination"
          :loading="tableLoading"
          :filter="filter"
          @request="getAccount"
          no-data-label="This account doesn't have any data to display."
          no-results-label="This account doesn't have any data to display."
        >
    // <table rows display fine here, but they are displayed in one giant data dump.>
    </q-table>
    
    </div>
    </template>
    
    <script>
    data () {
        return {
         // Table column props are defined here....
          pagination: {
            page: 1, 
            rowsPerPage: 10, // I think this determines the default number of rows actually displayed, but does not affect the server-side directly.
            sortBy: 'Timestamp',
            descending: true
            rowsNumber: 100 // I think this should be set to the same value as the server-side limit SQL query on the end-point, which limits the rows that Q-Table can fetch when the "Next" / "Previous" buttons are clicked.
          },
          tableLoading: false,
          filter: '' // I'm not sure how filtering works yet, but I think this is part of the query params that are sent to the server.
        }
      },
    
    methods() {
    onTableLoad (props) {
    // This code block is basically copied from the Q-Table server sync example. I generally understand how this logic works, but I'm still a little fuzzy about how it actually maps to the Next/Previous buttons and the server-side pagination logic.
    
          const { page, rowsPerPage, sortBy, descending } = props.pagination
    
          // What exactly does this filter prop do?
          const filter = props.filter
    
          this.tableLoading = true
    
          this.pagination.rowsNumber = this.getRowsNumberCount(filter)
    
          // get all rows if "All" (0) is selected
          const fetchCount = rowsPerPage === 0 ? this.pagination.rowsNumber : rowsPerPage
    
          // calculate starting row of data
          const startRow = (page - 1) * rowsPerPage
    
          // fetch data from server: 
          const returnedData = this.fetchFromServer(startRow, fetchCount, filter, sortBy, descending)
    
          // clear out existing data and add new
          this.data.splice(0, this.data.length, ...returnedData)
    
          // I think this page object should be incremented or decremented, but I'm not sure exactly when this should occur.
          this.pagination.page = page
          this.pagination.rowsPerPage = rowsPerPage
          this.pagination.sortBy = sortBy
          this.pagination.descending = descending
    
          // ... turn off loading indicator
          this.tableLoading = false
        }
    },
    
      mounted () {
        // Get initial table data from server (1st page).
        this.getAccount({
          pagination: this.pagination,
          filter: undefined
        })
    }
    
    </script>
    


  • @Julia as from the docs example, request event will trigger on filter/sort/pagination changes. etc… hence why you can see it loading when you do those stuff. as for how to implement, theres many tuts out there for the backend, since it depends on what backend you use but logic is all the same, what you should focus is what the frontend api needs and what it can offer, which can be seen in the example and api section of q-table.

    things i can point.

    onRequest (props) {
          const { page, rowsPerPage, sortBy, descending } = props.pagination
     ...
    
     /// and lines
        // don't forget to update local pagination object
        
                this.pagination.page = page
        
                this.pagination.rowsPerPage = rowsPerPage
        
                this.pagination.sortBy = sortBy
        
                this.pagination.descending = descending
    ...
    

    imo, the example is comprehensive enough to tackle most common pagination process, including yours.



  • Thank you for your reply. I finally got it.


Log in to reply