Getting Started With SharePoint Framework Development Using PnP JS

We can seamlessly integrate PnP JS file with SharePoint. The new Patterns and Practices JavaScript Core Library was created to help developers by simplifying common operations within SharePoint. Currently it contains a fluent API for working with the full SharePoint REST API as well as utility and helper functions. We can use them with SharePoint Framework to work with SharePoint with minimal effort. You can get detailed information and documentation about PnP JS from here.

Retrieve SharePoint List Items using PnP JS and SharePoint Framework

As part of this article, we will see how to create a SharePoint Framework webpart that retrieves List Items using PnP JS. The major project files used in this solution have been zipped and uploaded at Microsoft TechNet Gallery. Feel free to download it.

We can create the directory, where we will be adding the solution, using the command given below.

md PnPSPFrameworkGetItems

Let’s move to the newly created working directory, using the command.

cd PnPSPFrameworkGetItems

SharePoint

We will then create the client Web part by running the Yeoman SharePoint Generator.

yo @microsoft/sharepoint

SharePoint

This will display the prompt, which we will have to fill up, so as to proceed with the project creation.

  • What is your solution name? : Set it to ‘PnPSPFrameworkGetItems’.

On pressing enter, we will be asked to chose the working folder for the project.

  • Where do you want to place your files- Use current folder.
  • What framework would you like to start with- Select “No javaScript web framework” for the time being, as this is a sample Web part.
  • What is your Webpart name- We will specify it as ‘PnPSPFrameworkGetItems ‘and press Enter
  • What is your Webpart description- We will specify it as ‘Get SP Lit items using PnP’

    SharePoint

Yeoman has started working on the scaffolding of the project. It will install the required dependencies and scaffold the solution files for the ‘PnPSPFrameworkGetItems’ Web part, which will take some time to complete. Once completed, we will get a congratulations message.

SharePoint


Edit Webpart

Run Code to create the scaffolding and open the project in Visual Studio Code.

SharePoint

SharePoint

Now, we have to load PnP JS file which we will use within the project to create list. We will be using npm to add PnP JS file as shown below.

npm install sp-pnp-js --save

SharePoint

Define List Model

Since we want to retrieve an Employee list items data, we will be creating list model with SharePoint list fields in the PnPspFrameworkGetItems.TS file, as shown below. Place it above the ‘PnPspFrameworkGetItems’ class.

  1. export interface ISPList {  
  2.     EmployeeId: string;  
  3.     EmployeeName: string;  
  4.     Experience: string;  
  5.     Location: string;  
  6. }  

Create Mock HTTPClient to test data locally

In order to test the list item retrieval in the local workbench, we will create a mock store, which returns mock Employee list data. We will create a new file inside ‘src\webparts PnPspFrameworkGetItemsWebPart’ folder named MockHttpClient.ts, as shown below.

We will then copy the code given below into MockHttpClient.ts, as shown below.

  1. import {  
  2.     ISPList  
  3. } from './PnPspFrameworkGetItemsWebPart';  
  4. export default class MockHttpClient {  
  5.     private static _items: ISPList[] = [{  
  6.         EmployeeId: 'E123',  
  7.         EmployeeName: 'John',  
  8.         Experience: 'SharePoint',  
  9.         Location: 'India'  
  10.     }, ];  
  11.     public static get(restUrl: string, options ? : any): Promise < ISPList[] > {  
  12.         return new Promise < ISPList[] > ((resolve) => {  
  13.             resolve(MockHttpClient._items);  
  14.         });  
  15.     }  
  16. }  
SharePoint

We can now use the MockHttpClient class in the ‘PnPspFrameworkGetItems’ class. Let’s import the ‘MockHttpClient’ module by going to the PnPspFrameworkGetItemsWebPart.ts and pasting the line given below just after “import { IPnPspFrameworkGetItemsWebPartProps } from './I PnPspFrameworkGetItemsWebPartProps';”

  1. import MockHttpClient from './MockHttpClient';  

We will also add the mock list item retrieval method within the ‘PnPspFrameworkGetItemsWebPart’ class.

  1. private _getMockListData(): Promise < ISPList[] > {  
  2.     return MockHttpClient.get(this.context.pageContext.web.absoluteUrl).then(() => {  
  3.         const listData: ISPList[] = [{  
  4.             EmployeeId: 'E123',  
  5.             EmployeeName: 'John',  
  6.             Experience: 'SharePoint',  
  7.             Location: 'India'  
  8.         }, {  
  9.             EmployeeId: 'E567',  
  10.             EmployeeName: 'Martin',  
  11.             Experience: '.NET',  
  12.             Location: 'Qatar'  
  13.         }, {  
  14.             EmployeeId: 'E367',  
  15.             EmployeeName: 'Luke',  
  16.             Experience: 'JAVA',  
  17.             Location: 'UK'  
  18.         }];  
  19.         return listData;  
  20.     }) as Promise < ISPList[] > ;  
  21. }  

Retrieve SharePoint List Items

We will be making use of PnP library to get the list items as shown below,

  1. private _getListData(): Promise < ISPList[] > {  
  2.     return pnp.sp.web.lists.getByTitle("EmployeeList").items.get().then((response) => {  
  3.         return response;  
  4.     });  
  5. }  

Retrieve the SharePoint List Items From Employee List

Once we run the gulp serve command, we can test the Web part in SharePoint Workbench in the local environment or using SharePoint Online Context. SharePoint Framework uses ‘EnvironmentType’ module to identify the environment, where the Web part is executed.

To implement this, we will import ‘Environment’ and the ‘EnvironmentType’ modules from the @microsoft/sp-core-library bundle by placing it at the top of the PnPspFrameworkGetItemsWebpart.ts file. 

  1. import {  
  2.     Environment,  
  3.     EnvironmentType  
  4. } from '@microsoft/sp-core-library';   

We will then check Environment.type value and if it is equal to Environment.Local, the MockHttpClient method, which returns dummy data will be called else the method that calls REST API that will retrieve SharePoint list items will be called.

  1. private _renderListAsync(): void {  
  2.     if (Environment.type === EnvironmentType.Local) {  
  3.         _getMockListData().then((response) => {  
  4.             _renderList(response.value);  
  5.         });  
  6.     } else {  
  7.         _getListData().then((response) => {  
  8.             _renderList(response.value);  
  9.         });  
  10.     }  
  11. }   

Finally, we will add the method given below, which will create HTML table out of the retrieved SharePoint list items.

  1. private _renderList(items: ISPList[]): void {  
  2.     let html: string = '<table class="TFtable" border=1 width=100% style="border-collapse: collapse;">';  
  3.     html += `<th>EmployeeId</th><th>EmployeeName</th><th>Experience</th><th>Location</th>`;  
  4.     forEach((item: ISPList) => {  
  5.         html += `  
  6. <tr>  
  7. <td>${item.EmployeeId}</td>  
  8. <td>${item.EmployeeName}</td>  
  9. <td>${item.Experience}</td>  
  10. <td>${item.Location}</td>  
  11. </tr>  
  12. `;  
  13.     });  
  14.     html += `</table>`;  
  15.     const listContainer: Element = this.domElement.querySelector('#spListContainer');  
  16.     innerHTML = html;  
  17. }   

To enable rendering of the list items given above, we will replace Render method in the ‘PnPspFrameworkGetItemsWebPart’ class with the code given below.

  1. public render(): void {  
  2.     domElement.innerHTML = `  
  3. <div class="${styles.helloWorld}">  
  4. <div class="${styles.container}">  
  5. <div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">  
  6. <div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">  
  7. <span class="ms-font-xl ms-fontColor-white" style="font-size:28px">Welcome to SharePoint Framework Development using PnP JS Library</span>  
  8. <p class="ms-font-l ms-fontColor-white" style="text-align: left">Demo : Retrieve Employee Data from SharePoint List</p>  
  9. </div>  
  10. </div>  
  11. <div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">  
  12. <div style="background-color:Black;color:white;text-align: center;font-weight: bold;font-size:18px;">Employee Details</div>  
  13. <br>  
  14. <div id="spListContainer" />  
  15. </div>  
  16. </div>  
  17. </div>`;  
  18.     _renderListAsync();  
  19. }   

TS File Contents to retrieve list data using PnP

The entire TS file contents that was used to implement data retrieval in the SPFx webpart is given below,

  1. import pnp from 'sp-pnp-js';  
  2. import {  
  3.     Version  
  4. } from '@microsoft/sp-core-library';  
  5. import {  
  6.     BaseClientSideWebPart,  
  7.     IPropertyPaneConfiguration,  
  8.     PropertyPaneTextField  
  9. } from '@microsoft/sp-webpart-base';  
  10. import {  
  11.     escape  
  12. } from '@microsoft/sp-lodash-subset';  
  13. import {  
  14.     Environment,  
  15.     EnvironmentType  
  16. } from '@microsoft/sp-core-library';  
  17. import styles from './PnPspFrameworkGetItems.module.scss';  
  18. import * as strings from 'pnPspFrameworkGetItemsStrings';  
  19. import {  
  20.     IPnPspFrameworkGetItemsWebPartProps  
  21. } from './IPnPspFrameworkGetItemsWebPartProps';  
  22. import MockHttpClient from './MockHttpClient';  
  23. import {  
  24.     SPHttpClient  
  25. } from '@microsoft/sp-http';  
  26. export interface ISPList {  
  27.     EmployeeId: string;  
  28.     EmployeeName: string;  
  29.     Experience: string;  
  30.     Location: string;  
  31. }  
  32. export default class PnPspFrameworkGetItemsWebPart extends BaseClientSideWebPart < IPnPspFrameworkGetItemsWebPartProps > {  
  33.     private _getListData(): Promise < ISPList[] > {  
  34.         return pnp.sp.web.lists.getByTitle("EmployeeList").items.get().then((response) => {  
  35.             return response;  
  36.         });  
  37.     }  
  38.     private _renderListAsync(): void {  
  39.         if (Environment.type === EnvironmentType.Local) {  
  40.             _getMockListData().then((response) => {  
  41.                 _renderList(response);  
  42.             });  
  43.         } else {  
  44.             _getListData().then((response) => {  
  45.                 _renderList(response);  
  46.             });  
  47.         }  
  48.     }  
  49.     private _renderList(items: ISPList[]): void {  
  50.         let html: string = '<table class="TFtable" border=1 width=100% style="border-collapse: collapse;">';  
  51.         html += `<th>EmployeeId</th><th>EmployeeName</th><th>Experience</th><th>Location</th>`;  
  52.         forEach((item: ISPList) => {  
  53.             html += `  
  54. <tr>  
  55. <td>${item.EmployeeId}</td>  
  56. <td>${item.EmployeeName}</td>  
  57. <td>${item.Experience}</td>  
  58. <td>${item.Location}</td>  
  59. </tr>  
  60. `;  
  61.         });  
  62.         html += `</table>`;  
  63.         const listContainer: Element = this.domElement.querySelector('#spListContainer');  
  64.         innerHTML = html;  
  65.     }  
  66.     public render(): void {  
  67.         domElement.innerHTML = `  
  68. <div class="${styles.helloWorld}">  
  69. <div class="${styles.container}">  
  70. <div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">  
  71. <div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">  
  72. <span class="ms-font-xl ms-fontColor-white" style="font-size:28px">Welcome to SharePoint Framework Development using PnP JS Library</span>  
  73. <p class="ms-font-l ms-fontColor-white" style="text-align: left">Demo : Retrieve Employee Data from SharePoint List</p>  
  74. </div>  
  75. </div>  
  76. <div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">  
  77. <div style="background-color:Black;color:white;text-align: center;font-weight: bold;font-size:18px;">Employee Details</div>  
  78. <br>  
  79. <div id="spListContainer" />  
  80. </div>  
  81. </div>  
  82. </div>`;  
  83.         _renderListAsync();  
  84.     }  
  85.     private _getMockListData(): Promise < ISPList[] > {  
  86.         return MockHttpClient.get(this.context.pageContext.web.absoluteUrl).then(() => {  
  87.             const listData: ISPList[] = [{  
  88.                 EmployeeId: 'E123',  
  89.                 EmployeeName: 'John',  
  90.                 Experience: 'SharePoint',  
  91.                 Location: 'India'  
  92.             }, {  
  93.                 EmployeeId: 'E567',  
  94.                 EmployeeName: 'Martin',  
  95.                 Experience: '.NET',  
  96.                 Location: 'Qatar'  
  97.             }, {  
  98.                 EmployeeId: 'E367',  
  99.                 EmployeeName: 'Luke',  
  100.                 Experience: 'JAVA',  
  101.                 Location: 'UK'  
  102.             }];  
  103.             return listData;  
  104.         }) as Promise < ISPList[] > ;  
  105.     }  
  106.     protected get dataVersion(): Version {  
  107.         return Version.parse('1.0');  
  108.     }  
  109.     protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {  
  110.         return {  
  111.             pages: [{  
  112.                 header: {  
  113.                     description: strings.PropertyPaneDescription  
  114.                 },  
  115.                 groups: [{  
  116.                     groupName: strings.BasicGroupName,  
  117.                     groupFields: [  
  118.                         PropertyPaneTextField('description', {  
  119.                             label: strings.DescriptionFieldLabel  
  120.                         })  
  121.                     ]  
  122.                 }]  
  123.             }]  
  124.         };  
  125.     }  
  126. }   

Package and Deploy the Solution

Let’s run Gulp serve to package the solution.

SharePoint


Test the Web part in local SharePoint Workbench

Now, we can see the output generated in the local SharePoint Workbench.

SharePoint


Now let’s add the web part by clicking on the Plus sign.

SharePoint

Since the environment is local, the mock data has been used to generate the table, as shown below.

SharePoint


Test the Web part in SharePoint Online

Now, let’s test the Web part in SharePoint Workbench available in SharePoint Online. This time, the 'EnvironmentType' check will evaluate to SharePoint and the PnP method will be called to retrieve the list items from SharePoint list. Once we have login in to SharePoint Online, we can invoke the workbench by appending the text ‘_layouts/15/workbench.aspx’ to SharePoint Online URL.

SharePoint

It has picked up the list items from the list and displayed it as a table.

SharePoint


The major project files used in this solution has been zipped and uploaded at Microsoft TechNet Gallery. Feel free to download it.

Summary

Thus, we saw how to retrieve SharePoint List Items using SharePoint Framework and PnP JS.