How to create server-side pagination to get data in SharePoint list through SPFx-react?
Current code I am using:
import * as React from "react";
import { useEffect, useState } from "react";
// import { sp } from "@pnp/sp/presets/all";
// import { sp } from "@pnp/sp";
// import { sp } from 'sp-rest-explorer';
import {
SPHttpClient,
SPHttpClientResponse,
} from "@microsoft/sp-http";
import { Spinner } from "react-bootstrap";
import { IAllPublishDocumentProps } from "./IAllPublishDocumentProps";
export const PublishDoc = (props: IAllPublishDocumentProps) => {
const [isLoading, setIsLoading] = useState(true);
const [PublishDocument, setPublishDocuments] = useState([]);
const [currentPage, setCurrentPage] = useState(1);
const pageSize = 10;
useEffect(() => {
fetchData();
}, [currentPage]);
const fetchData = async () => {
setIsLoading(true);
try {
const url = `${props.context.pageContext.web.absoluteUrl}/_api/web/lists/getbytitle('TestPerformance')/items?&$top=10`;
const response: SPHttpClientResponse =
await props.context.spHttpClient.get(
url,
SPHttpClient.configurations.v1,
{
headers: {
Accept: "application/json;odata=nometadata",
"Content-Type": "application/json;odata=nometadata",
"odata-version": "",
},
}
);
const responsejson = await response.json();
console.log(responsejson);
const newData = responsejson.value.map((item: any) => ({
ID: item.ID,
GuidData: item.RUID,
OrignalID: item.OrignalID,
OLDTagID: item.OldTagId,
DocumentID: item.DocID,
DocumentName: item.DocumentName,
DocumentType: item.DocumentType,
SubmissionDate: item.Created,
RequestedBy: item.AuthorName,
Version: item.RevisionNo,
PublishDocument: item.DocName,
PublishDocument2:
props.context.pageContext.web.absoluteUrl +
"/_layouts/download.aspx?SourceUrl=" +
encodeURIComponent(item.EncodedAbsUrl),
}));
let url2 = `${props.context.pageContext.web.absoluteUrl}/_api/web/lists/getbytitle('TestPerformance')/items?$top=${pageSize}&$skiptoken=Paged=TRUE&p_ID=${newData[9].ID}`;
let nextdata = await props.context.spHttpClient.get(
url2,
SPHttpClient.configurations.v1,
{
headers: {
Accept: "application/json;odata=nometadata",
"Content-Type": "application/json;odata=nometadata",
"odata-version": "",
},
}
);
const nextdatajson = await nextdata.json();
console.log(nextdatajson);
setPublishDocuments(newData);
setIsLoading(false);
} catch (error) {
console.error("Error fetching data:", error);
setIsLoading(false);
}
};
const handlePageClick = (pageNumber: number) => {
setCurrentPage(pageNumber);
};
return (
<div>
{isLoading ? (
<div
className="d-flex flex-column align-items-center"
style={{ height: "100vh" }}
>
<Spinner animation="border" role="status" className="mb-2">
<span className="sr-only">Loading...</span>
</Spinner>
<p>Document loading...</p>
</div>
) : (
<div className="container-fluid">
<div className="row">
<div className="col-md-12">
<div className="card">
<div
className="card-heading text-center"
style={{ backgroundColor: "#ffe525", paddingTop: "5px" }}
>
<h3 className="text-black">All Published Document</h3>
</div>
</div>
<div className="card-body" style={{ padding: "0px" }}>
<div className="row">
<div
className="col-md-12 col-sm-11 col-xs-9"
style={{ fontSize: "small" }}
>
<nav
className="navbar navbar-expand-lg navbar-light"
style={{
backgroundColor: "#edeccc87",
fontWeight: "bold",
}}
>
<div
className="col-md-6 col-sm-1 col-xs-12"
style={{ paddingRight: "0px" }}
>
<button
style={{
padding: "0px",
marginLeft: "5px;",
borderRadius: "3px",
}}
className="navbar-toggler"
type="button"
// data-bs-toggle="collapse"
// data-bs-target="#navbarSupportedContent"
// aria-controls="navbarSupportedContent"
// aria-expanded="false"
// aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon"></span>
</button>
<div
style={{ width: "" }}
className="collapse navbar-collapse"
id="navbarSupportedContent"
>
<ul className="navbar-nav mr-auto">
{" "}
<li className="nav-item active">
{" "}
<a
className="nav-link"
// href="https://credentinfotec.sharepoint.com/sites/testPortal/SitePages/DMSDashboard.aspx"
href={
props.context.pageContext.web.absoluteUrl +
"/SitePages/NEWDMSDASHBOARD.aspx"
}
>
Home
</a>
</li>
<li className="nav-item" id="TempNav">
<a
className="nav-link"
// href="https://credentinfotec.sharepoint.com/sites/testPortal/SitePages/DMSTemplate.aspx"
href={
props.context.pageContext.web.absoluteUrl +
"/SitePages/DMSTemplate.aspx"
}
>
Templates
</a>
</li>{" "}
<li className="nav-item">
<a className="nav-link" href="#">
Reports
</a>
</li>
<li className="nav-item" id="adminPanel">
<a
className="nav-link"
href={
props.context.pageContext.web.absoluteUrl +
"/SitePages/MasterListUpdate.aspx"
}
>
Admin Panel
</a>
</li>
<li className="nav-item" id="archiveDoc">
<a
className="nav-link"
// href="https://credentinfotec.sharepoint.com/sites/testPortal/SitePages/ArchivalDocument.aspx"
href={
props.context.pageContext.web.absoluteUrl +
"/SitePages/ArchivalDocument.aspx"
}
>
Archive
</a>
</li>
<li className="nav-item" id="expireDocument">
<a
className="nav-link"
href={
props.context.pageContext.web.absoluteUrl +
"/SitePages/ExpiredDocument.aspx"
}
>
Expired Document
</a>
</li>
<li className="nav-item" id="approvalRoute">
<a
className="nav-link"
// // href="https://credentinfotec.sharepoint.com/sites/testPortal/SitePages/approvalRoutePage.aspx"
href={
props.context.pageContext.web.absoluteUrl +
"/SitePages/approvalRoutePage.aspx"
}
>
Approval route Creation
</a>
</li>
</ul>
</div>
</div>
<div className="col-md-6">
<a
href={
props.context.pageContext.web.absoluteUrl +
"/SitePages/NEWDMSDASHBOARD.aspx"
}
>
<button
style={{ marginLeft: "5px", float: "right" }}
type="button"
// value="Exit"
className="btn btn-danger"
>
Exit
</button>
</a>
<a
href={
props.context.pageContext.web.absoluteUrl +
"/SitePages/PublishPermissionPage.aspx"
}
>
<button
type="button"
id="givePermissionBtn"
style={{ float: "right", display: "none" }}
className="btn btn-primary"
// onClick={ModalBoxopen}
>
Give Permission
</button>
</a>
</div>
{/* Coding For Modal Box */}
</nav>
</div>
</div>
</div>
</div>
<div className="col-md-12">
<div
className="table-responsive"
style={{ overflowX: "auto", marginTop: "10px" }}
>
<table
className="table"
style={{ width: "100%", borderCollapse: "collapse" }}
>
<thead>
<tr>
<th
style={{
padding: "10px",
borderBottom: "1px solid #ddd",
background: "#f2f2f2",
}}
>
<span style={{ marginRight: "5px" }}>OLDTagID</span>
<input
type="text"
placeholder="Enter your TagID"
style={{
padding: "5px",
borderRadius: "5px",
border: "1px solid #ccc",
}}
/>
</th>
<th
style={{
padding: "10px",
borderBottom: "1px solid #ddd",
background: "#f2f2f2",
}}
>
<span style={{ marginRight: "5px" }}>DocumentID</span>
<input
type="text"
placeholder="Enter your DocumentID"
style={{
padding: "5px",
borderRadius: "5px",
border: "1px solid #ccc",
}}
/>
</th>
<th
style={{
padding: "10px",
borderBottom: "1px solid #ddd",
background: "#f2f2f2",
}}
>
<span style={{ marginRight: "5px" }}>DocumentName</span>
<input
type="text"
placeholder="Enter your DocumentName"
style={{
padding: "5px",
borderRadius: "5px",
border: "1px solid #ccc",
}}
/>
</th>
<th
style={{
padding: "10px",
borderBottom: "1px solid #ddd",
background: "#f2f2f2",
}}
>
<span style={{ marginRight: "5px" }}>DocumentType</span>
<input
type="text"
placeholder="Enter your DocumentType"
style={{
padding: "5px",
borderRadius: "5px",
border: "1px solid #ccc",
}}
/>
</th>
<th
style={{
padding: "10px",
borderBottom: "1px solid #ddd",
background: "#f2f2f2",
}}
>
<span style={{ marginRight: "5px" }}>
SubmissionDate
</span>
<input
type="text"
placeholder="Enter your SubmissionDate"
style={{
padding: "5px",
borderRadius: "5px",
border: "1px solid #ccc",
}}
/>
</th>
<th
style={{
padding: "10px",
borderBottom: "1px solid #ddd",
background: "#f2f2f2",
}}
>
<span style={{ marginRight: "5px" }}>RequestedBy</span>
<input
type="text"
placeholder="Enter your RequestedBy"
style={{
padding: "5px",
borderRadius: "5px",
border: "1px solid #ccc",
}}
/>
</th>
<th
style={{
padding: "10px",
borderBottom: "1px solid #ddd",
background: "#f2f2f2",
}}
>
<span style={{ marginRight: "5px" }}>Version</span>
<input
type="text"
placeholder="Enter your Version"
style={{
padding: "5px",
borderRadius: "5px",
border: "1px solid #ccc",
}}
/>
</th>
<th
style={{
padding: "10px",
borderBottom: "1px solid #ddd",
background: "#f2f2f2",
}}
>
<span style={{ marginRight: "5px" }}>
PublishedDocument
</span>
<input
type="text"
placeholder="Enter your PublishedDocument"
style={{
padding: "5px",
borderRadius: "5px",
border: "1px solid #ccc",
}}
/>
</th>
</tr>
</thead>
<tbody>
{PublishDocument.map((data: any, index: number) => (
<tr
key={index}
style={{ borderBottom: "1px solid #ddd" }}
>
{/* <td style={{ padding: "10px" }}>{data.OLDTagID}</td> */}
<td
style={{ border: "1px solid #ddd", padding: "5px" }}
>
{data.OLDTagID}
</td>
<td
style={{ border: "1px solid #ddd", padding: "5px" }}
>
{data.DocumentID}
</td>
<td
style={{ border: "1px solid #ddd", padding: "8px" }}
>
{data.DocumentName}
</td>
<td
style={{ border: "1px solid #ddd", padding: "8px" }}
>
{data.DocumentType}
</td>
<td
style={{ border: "1px solid #ddd", padding: "8px" }}
>
{data.SubmissionDate}
</td>
<td
style={{ border: "1px solid #ddd", padding: "8px" }}
>
{data.RequestedBy}
</td>
<td
style={{ border: "1px solid #ddd", padding: "8px" }}
>
{data.Version}
</td>
<td
style={{ border: "1px solid #ddd", padding: "8px" }}
>
{data.PublishDocument}
</td>
</tr>
))}
</tbody>
</table>
</div>
<nav aria-label="Page navigation example">
<ul className="pagination">
<li
className={`page-item ${
currentPage === 1 ? "disabled" : ""
}`}
>
<button
className="page-link"
onClick={() => handlePageClick(currentPage - 1)}
>
Previous
</button>
</li>
{/* Assuming you have at least one page */}
<li className="page-item">
<button
className="page-link"
onClick={() => handlePageClick(1)}
>
1
</button>
</li>
<li
className={`page-item ${
PublishDocument.length < pageSize ? "disabled" : ""
}`}
>
<button
className="page-link"
onClick={() => handlePageClick(currentPage + 1)}
>
Next
</button>
</li>
</ul>
</nav>
</div>
</div>
{/* // -----------------Re-loader------------------- */}
{!isLoading && PublishDocument.length === 0 && (
<div style={{ textAlign: "center" }}>No data available</div>
)}
{/* )} */}
</div>
)}
</div>
);
};
I'm trying to make server-side pagination to get the data in SharePoint list through SPFx react but problem is on the next click not giving me next 10 entry/data of list its give me same data every time in both API in second API I am sending my last id and I want the next 10 data of my last id.