How to Implement Pagination to Your Product?

By Prajwal Haniya

Techletter #34 | June 9, 2023

What is pagination?

Pagination is the most important thing when you have large lists to display for the user. So what does pagination mean? Pagination simply refers to the practice of dividing content or data into separate pages or sections. Believe me, it’s one of the important features of any application that has a large list to show to the user.

Pagination often includes navigation elements, such as page numbers, “previous” and “next” buttons, or “load more” functionality, to allow users to move between the different pages. So how to implement this? Here, I will explain how you can implement pagination using React, MUI and Nodejs.

Before moving ahead, I assume that you are already familiar with React and nodejs.

How to implement pagination?

In the MUI library, the pagination component is already present. So let’s make use of it along with the react. Once the component is imported then you can start writing both frontend and backend logic.

Pagination Component MUI

So go ahead and import the component to your code.

import { useState } from 'react';
import { Pagination } from '@mui/material';

function YourComponent() {
    const [lists, setLists] = useState([])
    const [total, setTotal] = useState(0);
    const [page, setPage] = useState(1);
    
    const handlePageChange = () => {
        // ...
    }

    let pages = parseInt(total / 10);
    const remaining = total % 10;
    if (remaining > 0) {
        pages += 1;
    }

    return (
        <>
            // All you required logic for list
          {
            total > 10 ?
            <>
                // Assuming you have installed bootstrap or other Style libraries
                <div className="pl-1 pt-2 pb-3 pr-2 mb-4 row m-0">
                    <div className="col-4 text-left text-muted p-0">{total} Compliances</div>
                        <div className="col-8 text-right p-0">
                            <Pagination count={pages} color="primary" page={page} variant="outlined" shape="rounded" onChange={handlePageChange} />
                        </div>                    
                    </div>
                </div>
                       
            </>
          }
        </>
    );
}

So now you have imported the pagination to your component. Now we need to write a few functions for the pagination to work. In the above code you can notice the onClick props where I am making use of handlePageChange function. So lets write it.

const handlePageChange = (event, newPage) => {
    setPage(newPage);
    // another function, which calls the API
    getLists(newPage * 10);
};

In the above code, the getLists(newPage * 10) is a function call, which in turn talks with the API with the given arguments.

const getLists= async (limit = 10) => {
    try {
        // I will make use of axios library to make API calls
        const result = await axios.post('/api/custom_endpoint', { limit });
        const { data } = result;
        // the response from api {success: true, message: [{List1}, {List2}]}
        if (data && data.success) {
            setLists(data.message);
        } else {
            setLists([]);
        }
    } catch (error) {
        console.log('Error while getting the lists');
    }
}

This basically completes your frontend. Now, you can start writing backend APIs. Here, I will be showing how you can write a simple service to send the data to the frontend. I assume that you already know how to write a basic API endpoint in nodejs. If not, you can refer to this.

app.post('/custom_endpoint', async (req,res) => {
    const data = await services.getAllLists(params);
    res.json(data)
})

// Your API will make use of the below service
const self = module.exports = {
    getAllLists: async (params) => {
        try {
            let { limit } = params;
            if (limit) {
                limit = limit > 10 ? limit - 10 : 0;
            } else {
                limit = 0;
            }
            // If you are using sequelize else you can directly query with limit & offset
            const data = await models.YOUR_MODEL.findAndCountAll({
                //... All other required information
                limit: [limit, 10],
                raw: true,
                nest: true
            });
            return { success: true, message: data};
        } catch (error) {
            console.log('Error');
            return { success: false, message: 'Error' };
        }
    }
}

So, this completes your pagination implementation to your lists.

In the above code I have extensively used asynchronous programming in javascript. If you don’t know what asynchronous programming then you can read about it in this article.