Mastering SharePoint Framework (SPFx) Development: Deep Dive into PnP for SharePoint

In this second article of the series, we will explore PnP (Patterns and Practices) for SharePoint development, which is essential for building efficient, scalable, and maintainable SharePoint solutions. PnP provides a set of open-source tools and libraries that simplify many of the common tasks developers encounter when interacting with SharePoint data.

If you’re looking to streamline your development process, reduce code complexity, and leverage best practices, mastering PnP is a must.


What is PnP for SharePoint?

PnP is an open-source initiative led by Microsoft and the community to provide tools and reusable components for SharePoint development. The core objective of PnP is to offer a standardized way of interacting with SharePoint and Office 365 APIs, thus making developers’ lives easier by abstracting away repetitive tasks like querying lists, libraries, handling authentication, and managing permissions.

PnP provides a collection of libraries such as @pnp/sp, @pnp/pnpjs, and @pnp/graph to simplify common operations like:

  • Querying SharePoint lists and libraries
  • Managing content types and fields
  • Handling documents and files
  • Accessing user profile data
  • Dealing with permissions and security

PnP is widely used because it significantly reduces the amount of code required to perform these operations, improves maintainability, and adheres to SharePoint’s best practices.


Setting Up PnP in Your SPFx Project

To use PnP in your SPFx project, you first need to install the PnP libraries. Here’s how to get started.

1. Install PnP Libraries

Navigate to your SPFx project directory and install the PnP libraries using npm:

npm install @pnp/sp @pnp/logging @pnp/common @pnp/odata --save

These libraries provide the core functionality for working with SharePoint data, logging, and making HTTP requests.

2. Import and Configure PnP in Your Web Part

After installing the PnP libraries, you need to configure your web part to use them. Open your SPFx web part file (for example, MyFirstSpfxWebPart.tsx) and import the necessary modules:

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

Next, initialize the PnP context in the onInit method of your web part:

import { WebPartContext } from "@microsoft/sp-webpart-base";

export default class MyFirstSpfxWebPart extends BaseClientSideWebPart<IMyFirstSpfxWebPartProps> {

  public onInit(): Promise<void> {
    return super.onInit().then(_ => {
      sp.setup({
        spfxContext: this.context as WebPartContext
      });
    });
  }
}

This sets up the PnP library to communicate with SharePoint using the context of your current SPFx web part.


Querying SharePoint Lists and Libraries with PnP

One of the most common tasks in SharePoint development is working with lists and libraries. Let’s look at how PnP simplifies querying lists and items.

1. Retrieving All Items from a List

To retrieve all items from a SharePoint list, you can use the sp.web.lists.getByTitle() method provided by PnP:

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

export default class MyFirstSpfxWebPart extends BaseClientSideWebPart<IMyFirstSpfxWebPartProps> {

  public render(): void {
    this._getListItems().then(items => {
      let listItemsHtml = items.map(item => `<li>${item.Title}</li>`).join("");
      this.domElement.innerHTML = `<ul>${listItemsHtml}</ul>`;
    });
  }

  private async _getListItems(): Promise<any[]> {
    const items = await sp.web.lists.getByTitle("MyCustomList").items();
    return items;
  }
}

In this example, we retrieve all items from the SharePoint list named “MyCustomList” and render them as a list in the web part.

2. Retrieving Specific Fields from a List

If you only need specific fields (e.g., Title, ID), you can specify them using select:

const items = await sp.web.lists.getByTitle("MyCustomList").items.select("Title", "ID").get();

This retrieves only the Title and ID fields from the list, reducing the amount of data transferred and improving performance.

3. Filtering List Items

To filter items based on conditions (for example, retrieving only items with a specific status), you can use the filter method:

const filteredItems = await sp.web.lists.getByTitle("MyCustomList").items
  .filter("Status eq 'Active'")
  .get();

This example retrieves items from “MyCustomList” where the Status field is equal to ‘Active’.


Creating and Updating List Items with PnP

In addition to querying, PnP makes it easy to create and update list items.

1. Creating a New Item

Here’s how you can add a new item to a SharePoint list using PnP:

await sp.web.lists.getByTitle("MyCustomList").items.add({
  Title: "New Item Title",
  Status: "Active"
});

This creates a new item in the “MyCustomList” list with the specified Title and Status.

2. Updating an Existing Item

To update an existing item, you’ll need the ID of the item you want to modify:

await sp.web.lists.getByTitle("MyCustomList").items.getById(1).update({
  Title: "Updated Item Title",
  Status: "Inactive"
});

This updates the item with ID 1, changing its Title and Status fields.


Working with Document Libraries Using PnP

Document libraries are similar to lists, but they store files and folders. PnP makes it easy to interact with libraries and files.

1. Uploading a File to a Document Library

Here’s how to upload a file to a SharePoint document library using PnP:

const file = this._getFileFromInput(); // Assume this method retrieves the file from an input element
await sp.web.lists.getByTitle("Documents").rootFolder.files.add(file.name, file, true);

This uploads a file to the “Documents” library. The third parameter (true) specifies that the file should be overwritten if it already exists.

2. Downloading a File from a Document Library

To download a file, you can use the following code:

const fileBuffer = await sp.web.getFileByServerRelativeUrl("/sites/mysite/Shared Documents/MyFile.pdf").getBuffer();

This retrieves the file as a buffer, which can then be used to display or save the file.


Best Practices with PnP in SPFx Development

To get the most out of PnP, keep the following best practices in mind:

  1. Use Select and Filter: Always use select and filter to reduce the amount of data retrieved from SharePoint. This improves both performance and efficiency.
  2. Batch Requests: Use batching to group multiple requests together. This reduces the number of HTTP requests made to SharePoint, which can greatly improve performance in scenarios where multiple list operations are needed.
  3. Error Handling: Implement proper error handling for network requests to ensure your web parts handle failures gracefully.

Next Steps

In this article, we explored the power of PnP for SharePoint development, focusing on querying, creating, and updating list items. PnP is a must-have tool for any SharePoint developer looking to streamline their workflow and adhere to best practices.

In the next article of this series, we’ll shift our focus to Fluent UI, a modern UI library from Microsoft that helps create responsive and accessible user interfaces for your SharePoint solutions.

Stay tuned, and don’t hesitate to reach out if you have any questions or comments!


This article introduces you to the fundamentals of using PnP in SPFx development. In the next installments of this series, we will explore more advanced topics, including Fluent UI and complex web part development.

Edvaldo Guimrães Filho Avatar

Published by

Categories:

Leave a comment