Get SharePoint list items using PNP/SP - React in SPFX web part

Hope this post finds you well.

I have just started learning SPFX and and I found it pretty interesting using React. TypeScript is a whole new world than a legacy development technique. It gives you new ways to think and implement your code. Let start working and stop talking.

Note: Before starting this article, it is assumed that you have already setup your environment according to Microsoft's guidelines. This is very important that you read and perform all the installation steps carefully as if there will be a minor change in the installation software versions, you won't be able to do many operations later on.

Steps that we'll do to achieve this task are below:

  1. Create solution and web part using YO.
  2. Install PNP/SP
  3. Create SharePoint list
  4. Write React and PNP code
  5. Test web part on workbench
Lets start...! 

1. Create solution and web part using YO.

First, lets create a solution and choose a web part to create. For this, create a folder in your drive with the project name. Now, open command prompt and navigate to this folder.

Unlike legacy UI method of creating solution, you have to create that here using commands.

yo @microsoft/sharepoint

After running this command, it will ask you few questions. Choose the options that I chose and it will start creating solution and a web part with the provided name for you.


You can check that it has started creating folders and structure for your solution in the same directory.


Khalli Walli (ignore) the warnings you see during project creation.



Once it finishes, you will see something like this.



2. Install PNP/SP
Stay in the same directory and run below command. It will download and install some packages on your machine which are required to run for code.

npm install @pnp/sp --save



Now, run Code . in your command prompt being on the same path where your code is and the code should load in your Visual Studio Code.


And it should load your project like this.


3. Create SharePoint list

Navigate to your SharePoint site and create the list. I am using below columns and data as sample.


4. Write React and PNP code
We have to modify our WebPart.ts file as located on below path with the following code. This code will start the context on initialization.

..\PlayingWithSPList\src\webparts\getAllStudents\GetAllStudentsWebPart.ts

import { sp } from "@pnp/sp/presets/all";

Below code should fall under the web part export class.

   //Context is required in order to make query to SharePoint list
   protected onInit(): Promise<void> {
    return super.onInit().then(_ => {
      sp.setup({
        spfxContext: this.context
      });
    });
  }

It should look like below.


Now, let work with our main file where we have to put our logics.

..\PlayingWithSPList\src\webparts\getAllStudents\components\GetAllStudents.tsx

Import the following PNP files.

import { sp } from "@pnp/sp/presets/all";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";

Create an interface right after the import. You can also create this in a separate file and then import. However, for this small exercise lets put it here. You can name it anything, I named it IListColumnsState  and studentsItems according to the my naming convention.

export interface IListColumnsState {
  studentsItems: any[];
}


If you are familiar with programming, you will already know that an interface is just virtual structure or face of the actual class. In TypeScript language, we have to set the state of the object we have. For example, here we need to set the state  of studentsItems in the constructor.

  //Create constructor to set state
  constructor(props: IGetAllStudentsProps, state: IListColumnsState) {
    super(props);
    this.state = {
      studentsItems: []
    };
  }

Now, lets get the items from the list using a method. All these methods  and constructors should be under the class of your web part. Only Imports and Interfaces needs to be typed outside the class. You can check the full code later below to understand this.

  //Get all items from list
  private getAllItems = async () => {
    try {
      const items: any[] =
        await sp.web.lists
          .getByTitle("My Students")
          .items
          .filter('isActive eq 1')
          .get();
      this.setState({ studentsItems: items });
      console.log(this.state.studentsItems);
    }
    catch (e) {
      console.error(e);
    }
  }


In previous programming languages like C# or VB, we had events like Page Init, Page Load etc, here we have componentDidMount where we can all our method we created above so that it should fetch all the data on mounting the component (or while page load in old sentiments).

 //call the created get data function
  public componentDidMount(): void {
    this.getAllItems();
  }

Now, we have got our data, we need to populate it somewhere to show on page. Here comes the render() method which actually renders the returned HTML.

Note : Notice the spaces between column names we created in SharePoint list VS the way we have used in our render code.

return (
      <div>
        <h3> Students Details</h3>
        <br></br>


        {/* Loop for ietrating through the students records */}
        {this.state.studentsItems
          && this.state.studentsItems.length > 0
          && this.state.studentsItems.map((item, index) => {
            return (
              <>
                {/* The above <> tag is required to concat multiple HTML tags in one return () function */}


                <h2>{item["Title"] + item["StudentName"]}</h2>
                <p> Roll Number : {item["RollNumber"]} </p>
                <p> Website Link : {item["WebSiteLink"].Url} </p>
                <img src={JSON.parse(item["StudentPicture"]).serverRelativeUrl}></img>
              </>
            );
          }
          )}


      </div>
    );


The whole code in one go is below. Notice the placement of elements, the calling of methods and rendering the HTML approach.

import * as React from 'react';
import { IGetAllStudentsProps } from './IGetAllStudentsProps';
import { escape } from '@microsoft/sp-lodash-subset';

import { sp } from "@pnp/sp/presets/all";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";

export interface IListColumnsState {
  studentsItems: any[];
}

export default class GetAllStudents extends React.Component<IGetAllStudentsProps, IListColumnsState> {

  //Create constructor to set state
  constructor(props: IGetAllStudentsProps, state: IListColumnsState) {
    super(props);
    this.state = {
      studentsItems: []
    };
  }

  //Get all items from list
  private getAllItems = async () => {
    try {
      const items: any[] =
        await sp.web.lists
          .getByTitle("My Students")
          .items
          .filter('isActive eq 1')
          .get();
      this.setState({ studentsItems: items });
      console.log(this.state.studentsItems);
    }
    catch (e) {
      console.error(e);
    }
  }

  //call the created get data function
  public componentDidMount(): void {
    this.getAllItems();
  }

  public render(): React.ReactElement<IGetAllStudentsProps> {
    return (
      <div>
        <h3> Students Details</h3>
        <br></br>


        {/* Loop for ietrating through the students records */}
        {this.state.studentsItems
          && this.state.studentsItems.length > 0
          && this.state.studentsItems.map((item, index) => {
            return (
              <>
                {/* The above <> tag is required to concat multiple HTML tags in one return () function */}


                <h2>{item["Title"] + item["StudentName"]}</h2>
                <p> Roll Number : {item["RollNumber"]} </p>
                <p> Website Link : {item["WebSiteLink"].Url} </p>
                <img src={JSON.parse(item["StudentPicture"]).serverRelativeUrl}></img>
              </>
            );
          }
          )}


      </div>
    );
  }
}



5. Test web part on workbench

Its time to test now. Lets compile and deploy to test. Here in SPFX and SharePoint Online, compilation is different. Run the below command in command prompt to compile and add web part.

Note: Before running the command, make sure your path to the site is set in serve.json


Run Gulp Serve


Add the web part.


The data is here. (Sorry for no CSS at the moment.)


Since we have already exported data in our console.log() while fetching from SharePoint, you can also see what was returned from SharePoint.


Happy SharePointing 😊






Comments

Popular Posts

GREYCstoration Oil Paint plugin for Photoshop

Service Bus Gateway service stuck at Starting

PowerApps SubmitForm not clearing People Picker value

Apple iPhone sending SMS automatically 00447786205094

SharePoint online hub navigation not updating for other users