How To Paginate An Array In Javascript

I was recently tasked with implementing pagination for an array of values (in some instances, over 2400 of them) and instead of using an existing library, I opted to write my own pagination logic and put it into an Aurelia value converter.

There are a lot of ways you can achieve this, you can use slice, you can use filter and reduce as well. The solution I ended up coming up with uses slice because it produces the easiest to read and simple code. Performance-wise, I do believe that filter comes out on top, but that isn’t our concern here.

const paginate = (items, page = 1, perPage = 10) => items.slice(perPage \* (page - 1), perPage \* page);

However, if you want something a little more descriptive, you can get a little more verbose and produce something that while not nearly as concise, gives you some more details.

In my instance, I wanted to return the next and previous pages, as well as the total number of pages and items for each page that is being paginated. While you get a more verbose method, it becomes a lot more useful.

const paginate = (items, page = 1, perPage = 10) => {
    const offset = perPage \* (page - 1);
    const totalPages = Math.ceil(items.length / perPage);
    const paginatedItems = items.slice(offset, perPage \* page);
  
    return {
        previousPage: page - 1 ? page - 1 : null,
        nextPage: (totalPages > page) ? page + 1 : null,
        total: items.length,
        totalPages: totalPages,
        items: paginatedItems
    };
};

If you’re using Aurelia, here is a value converter which will give you array pagination that can be used on a repeat.for or anywhere else you’re display items from an array. If you’re not using Aurelia, you can stop reading here, the above is what you’re after.

export class PaginateValueConverter {
    toView(array, page = 1, perPage = 10) {
        if (!array) {
            return array;
        }

        const paginationObject = paginate(array, page, perPage);

        return paginationObject.items;
    }
}

You can then use this value converter in your Aurelia applications like this:

-   ${item.name}

You would probably have a currentPage variable in your view-model, where you increment the value if a button or link is pressed, maybe a row of numbers.

-   ${item.name}