When your application has hundreds of records, fetching and displaying all of them at once is slow. The solution is Pagination—breaking the data into smaller, numbered pages. In this tutorial, we will add “Next” and “Previous” buttons to our blog post list and display the current page information.
Prerequisites
You must have a page that displays a list of posts from your database. For this tutorial to be effective, make sure you have at least 10-15 sample posts in yourPosts table.
Part 1: Set Up the State for Pagination
We need new state variables to keep track of our pagination status.- Navigate to your post list page.
- Select the
Bodyand go to the States tab. - Add or update the following state variables:
postList(Data Type:PostsData Table, Is List?:true)isLoading(Data Type:Boolean, Default Value:true)currentPage(Data Type:Number, Default Value:1)itemsPerPage(Data Type:Number, Default Value:5)totalPosts(Data Type:Number, Default Value:0)
Part 2: Build the ‘On Page Load’ Workflow
This workflow will run when the page first loads, fetching the initial page of data and the total number of posts.1
1. Fetch the First Page of Posts
- Open the “On Page Load” workflow from the Logic tab.
- Add a “Set data in state” action.
- Target State:
postList. - New Value: In the expression editor, select “Get data from DB”.
- Table:
Posts. - Limit: Bind this to your
itemsPerPagestate. - Offset: Build the expression
(currentPage - 1) * itemsPerPage. This will correctly be0on the first page load.
- Table:
2
2. Get the Total Number of Posts
- Add a second “Set data in state” action.
- Target State:
totalPosts. - New Value: We will fetch the entire list and then get its
length.
- In the expression editor, select “Get data from DB”.
- Table:
Posts. Do not set a Limit or Offset. - After the “Get data from DB” node, add an Operation and choose the
lengthoperation.
3
3. Update the Loading State
- Add a third “Set data in state” action at the very end.
- Target State:
isLoading. - New Value: Set it to
false.
Part 3: Build the Pagination Buttons (The Basic Way)
Now, let’s create the buttons to change pages.- Add the Buttons: On your page, add two Buttons: “Previous” and “Next”.
- “Next” Button Workflow:
- Create an “On Click” workflow.
- Action 1:
Set data in stateto updatecurrentPagetocurrentPage + 1. - Action 2:
Set data in stateto updatepostList. You must copy and paste the entire data fetch expression from Part 2 here.
- “Previous” Button Workflow:
- Do the same, but set
currentPagetocurrentPage - 1, followed by the same copied data fetch expression.
- Do the same, but set
This works, but notice the repetition? You’ve used the exact same data fetch
logic in three different places (On Page Load, Next Button, Previous Button).
If you need to change how you fetch data, you’ll have to update it in all
three places. Let’s fix this with a Function.
Part 4: Refactor with a Reusable Function (The Better Way)
Instead of putting our data-fetching logic directly on the page, we will create a self-contained “recipe” for it.1
1. Create a New Function
- Go to Data → Functions.
- Create a new Client-side Function named
fetchPosts.
2
2. Define the Function's Props (Its Inputs)
Our function needs to know which page to fetch and how many items to get per page. Add two Props:
pageToFetch(Data Type:Number)limit(Data Type:Number)
3
3. Build the Function's Workflow
The function’s job is to fetch the data and then return it.
- In the workflow editor for your
fetchPostsfunction, add the “Return function result” action. This must be the only action. - In the
valuefield of this action, build your data-fetching expression:- Select “Get data from DB”.
- Table:
Posts. - Limit: Bind this to the
limitProp. - Offset: Build the expression
(pageToFetch - 1) * limit. Crucially, use thepageToFetchandlimitProps from the function itself.
This function is now a perfect “black box”. It accepts two inputs (
pageToFetch and limit) and returns a list of posts. It has no knowledge of the page it’s being called from.1
1. Update the 'On Page Load' Workflow
- Open the “On Page Load” workflow for your post list page.
- Action 1: Trigger the Function to Fetch Posts
- Add the “Trigger Function” action.
- Function:
fetchPosts. - Props:
pageToFetch: Pass thecurrentPagestate (which is1).limit: Pass theitemsPerPagestate.
- Result: In the
Resulttab of the action, save the returned list of posts into yourpostListstate variable.
- Action 2: Get the Total Count
- Add a
Set data in stateaction to set thetotalPostsstate by fetching all posts and applying alengthoperation.
- Add a
- Action 3: Update Loading State
- Add a
Set data in stateaction to setisLoadingtofalse.
- Add a
2
2. Build the 'Next' Button Workflow
- Select the “Next” button and create an “On Click” workflow.
- Action 1: Increment the Page Number
- Add a
Set data in stateaction to updatecurrentPagetocurrentPage + 1.
- Add a
- Action 2: Trigger the Function Again
- Add a “Trigger Function” action.
- Function:
fetchPosts. - Props: Pass the
currentPageanditemsPerPagestates. This will use the newly updated page number. - Result: Save the returned value into the
postListstate. This will update the UI.
3
3. Build the 'Previous' Button Workflow
- Create the workflow for the “Previous” button. It will be the same as the “Next” button, but you will decrement the
currentPagestate in the first action.
Part 4: Add Conditional Logic for a Professional UI
Finally, let’s disable the buttons when they can’t be used and show the user where they are.- Disable the “Previous” Button:
- Select the “Previous” button. In its Properties Panel, bind the
Disabledproperty to the expression:currentPage <= 1.
- Select the “Previous” button. In its Properties Panel, bind the
- Disable the “Next” Button:
- Select the “Next” button. Bind its
Disabledproperty to the expression:currentPage * itemsPerPage >= totalPosts.
- Select the “Next” button. Bind its
- Display Page Info:
- Add a Text element and bind its content to a dynamic expression to show something like:
Page [currentPage] of [ceil(totalPosts / itemsPerPage)].
- Add a Text element and bind its content to a dynamic expression to show something like: