Hello friends, In today's post we will see an example that helps you to implement server-side pagination in lightning web component (lwc). So let's get started,

Server side pagination in lightning web component

In this web component i have used account sobject, you can use any salesforce object to implement this example.

ServerSidePaginationHandler.apxc

 public class ServerSidePaginationHandler {

@AuraEnabled
public static String getAccountData(Integer pageSize, Integer pageNumber){
String jsonData = '';
Integer offset = (pageNumber - 1) * pageSize;
Integer totalRecords = [SELECT COUNT() FROM Account];
Integer recordEnd = pageSize * pageNumber;
WrapperClass objcls = new WrapperClass();
objcls.pageSize = pageSize;
objcls.pageNumber = pageNumber;
objcls.recordStart = offset + 1;
objcls.recordEnd = totalRecords >= recordEnd ? recordEnd : totalRecords;
objcls.totalRecords = totalRecords;
objcls.accounts = [SELECT Id, Name, AccountNumber, Industry, Phone FROM Account order by Name asc LIMIT :pageSize OFFSET :offset];
jsonData = JSON.serialize(objcls);
return jsonData;
}

public class WrapperClass {
public Integer pageSize {get;set;}
public Integer pageNumber {get;set;}
public Integer totalRecords {get;set;}
public Integer recordStart {get;set;}
public Integer recordEnd {get;set;}
public List<Account> accounts {get;set;}
}
}
ServerSidePagination.html
 <template>
<template if:true={loader}>
<lightning-spinner alternative-text="Loading..." size="small"></lightning-spinner>
</template>
<div class="slds-box slds-theme_default">
<lightning-card title="Server Side Pagination on Account" icon-name="standard:record">
<table class="slds-table slds-table_cell-buffer slds-table_bordered">
<thead>
<tr class="slds-line-height_reset slds-text-title_caps">
<th class="slds-is-resizable" scope="col">
<div class="slds-truncate" title="Name">
Name
</div>
</th>
<th class="slds-is-resizable" scope="col">
<div class="slds-truncate" title="Account Number">
Account Number
</div>
</th>
<th class="slds-is-resizable" scope="col">
<div class="slds-truncate" title="Industry">
Industry
</div>
</th>
<th class="slds-is-resizable" scope="col">
<div class="slds-truncate" title="Phone">
Phone
</div>
</th>
</tr>
</thead>
<tbody>
<template if:true={accounts}>
<template for:each={accounts} for:item="acc">
<tr key={acc.Id}>
<th scope="row" data-label="Name">
<div class="slds-truncate" title={acc.Name}>{acc.Name}</div>
</th>
<th scope="row" data-label="Account Number">
<div class="slds-truncate" title={acc.AccountNumber}>{acc.AccountNumber}</div>
</th>
<th scope="row" data-label="Industry">
<div class="slds-truncate" title={acc.Industry}>{acc.Industry}</div>
</th>
<th scope="row" data-label="Phone">
<template if:true={acc.Phone}>
<div class="slds-truncate" title={acc.Phone}>{acc.Phone}</div>
</template>
</th>
</tr>
</template>
</template>
</tbody>
</table>
<template if:true={isDisplayNoRecords}>
<div class="slds-align_absolute-center">
<br/>
No records found
</div>
</template>
<br/>
<div class="slds-align_absolute-center">
<div class="slds-p-right_xx-small">
<lightning-button label="Previous" disabled={isPrev} onclick={handlePrev} variant="brand"
icon-name="utility:chevronleft" name="prev"></lightning-button>
</div>
<span class="slds-badge slds-badge_lightest">
{recordStart}-{recordEnd} of {totalRecords} | Page {pageNumber} of {totalPages}
</span>
<div class="slds-p-left_xx-small">
<lightning-button label="Next" disabled={isNext} onclick={handleNext} variant="brand"
icon-name="utility:chevronright" icon-position="right" name="next"></lightning-button>
</div>
</div>
</lightning-card>
</div>
</template>
ServerSidePagination.js
 import { LightningElement, track } from 'lwc';
import getAccountData from '@salesforce/apex/ServerSidePaginationHandler.getAccountData';
export default class ServerSidePagination extends LightningElement {
@track loader = false;
@track error = null;
@track pageSize = 10;
@track pageNumber = 1;
@track totalRecords = 0;
@track totalPages = 0;
@track recordEnd = 0;
@track recordStart = 0;
@track isPrev = true;
@track isNext = true;
@track accounts = [];

connectedCallback() {
this.getAccounts();
}

handleNext() {
this.pageNumber = this.pageNumber + 1;
this.getAccounts();
}

handlePrev() {
this.pageNumber = this.pageNumber - 1;
this.getAccounts();
}

getAccounts() {
this.loader = true;
getAccountData({ pageSize: this.pageSize, pageNumber: this.pageNumber })
.then(result => {
this.loader = false;
if (result) {
var resultData = JSON.parse(result);
this.accounts = resultData.accounts;
this.pageNumber = resultData.pageNumber;
this.totalRecords = resultData.totalRecords;
this.recordStart = resultData.recordStart;
this.recordEnd = resultData.recordEnd;
this.totalPages = Math.ceil(resultData.totalRecords / this.pageSize);
this.isNext = (this.pageNumber == this.totalPages || this.totalPages == 0);
this.isPrev = (this.pageNumber == 1 || this.totalRecords < this.pageSize);
}
})
.catch(error => {
this.loader = false;
this.error = error;
});
}

get isDisplayNoRecords() {
var isDisplay = true;
if (this.accounts) {
if (this.accounts.length == 0) {
isDisplay = true;
} else {
isDisplay = false;
}
}
return isDisplay;
}
}
ServerSidePagination.js-meta.xml
 <?xml version="1.0"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>51.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>

Output:

 Hope you like this post, for any feedback or suggestions please feel free to comment. I would appreciate your feedback and suggestions.
Thank you.