0

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.

1 Answer 1

0

You need to take into account the page you are in and calculate the items you need to skip when you are requesting the query.

const skip = pageSize * currentPage;
const url = `${props.context.pageContext.web.absoluteUrl}/_api/web/lists/getbytitle('TestPerformance')/items?$skip=${skip}&$top=${pageSize}`

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.