Working with PnPjs and Async Functions in SharePoint Framework (SPFx)

In modern web development, asynchronous operations are critical, especially when interacting with external APIs such as SharePoint REST APIs. SharePoint Framework (SPFx) and PnPjs simplify communication with SharePoint, making data fetching and list management straightforward. In this article, we’ll explain a practical example of retrieving data from a SharePoint list using PnPjs in an SPFx web part.

Code Overview

Let’s walk through a code snippet that shows how to fetch items from a SharePoint list called “paises” using PnPjs in an asynchronous manner.

The Code

protected async getListItems() {
  const sp = spfi().using(SPFx(this.context)); 

  const list = sp.web.lists.getByTitle("paises");

  // Use 'await' to fetch the data asynchronously
  const r = await list.select("Title")();
  console.log(r);
}

protected async onInit(): Promise<void> {
  return this._getEnvironmentMessage().then(message => {
    this._environmentMessage = message;

    this.getListItems();
  });
}

Key Components

Let’s break down the code and explain each part in detail.

getListItems() Function

This is an async function that retrieves data from the “paises” SharePoint list. Here’s a breakdown of each part:

  1. async Keyword:
  • The function is marked as async, meaning it will return a Promise. This allows the function to handle asynchronous operations using the await keyword.
  1. PnPjs Initialization:
   const sp = spfi().using(SPFx(this.context)); 
  • This line initializes PnPjs, specifically using the spfi function (introduced in PnPjs v3.x) to create a fluent API instance.
  • The SPFx(this.context) part provides the necessary SPFx context so that PnPjs can make authenticated requests to SharePoint.
  1. Retrieving the List:
   const list = sp.web.lists.getByTitle("paises");
  • This retrieves a specific list titled “paises” from the SharePoint web. The getByTitle method allows you to fetch a list by its name.
  1. Fetching List Items:
   const r = await list.select("Title")();
  • The select("Title") method is used to specify that we only want to retrieve the “Title” field from the list items.
  • await is used to wait for the asynchronous request to complete before proceeding to the next line. The result, r, will contain the list items with the “Title” field.
  1. Logging the Result:
   console.log(r);
  • Finally, the fetched list items are logged to the console. This is useful for debugging or verifying that the data retrieval was successful.

onInit() Method

The onInit() method is part of the SPFx web part lifecycle. This method is called when the web part is initialized. Here’s what happens in this function:

  1. async Keyword:
  • Just like getListItems(), the onInit() method is marked as async, which allows it to use asynchronous functions.
  1. Calling _getEnvironmentMessage():
   return this._getEnvironmentMessage().then(message => {
     this._environmentMessage = message;
   });
  • The _getEnvironmentMessage() is a custom function (assumed to return a Promise) that retrieves some environment-specific information. Once this Promise resolves, it stores the result in a variable _environmentMessage.
  1. Calling getListItems():
   this.getListItems();
  • After retrieving the environment message, the getListItems() function is called to fetch the list items from the “paises” SharePoint list.

Why Use await?

In JavaScript, asynchronous operations (like HTTP requests) don’t block the main execution thread. To deal with the delay in data retrieval, we use Promises. Instead of using callback functions, you can use async/await to write asynchronous code that reads more like synchronous code. This makes it easier to understand and manage.

In this code, the await keyword is used to pause the execution of the function until the Promise returned by list.select("Title")() resolves, ensuring that the list data is fully retrieved before moving forward.

Error Handling (Recommended)

To make your code more robust, you should add error handling using try and catch. Here’s how you can modify the getListItems() function to handle errors gracefully:

protected async getListItems() {
  try {
    const sp = spfi().using(SPFx(this.context)); 
    const list = sp.web.lists.getByTitle("paises");

    const r = await list.select("Title")();
    console.log(r);
  } catch (error) {
    console.error("Error fetching list items:", error);
  }
}

This ensures that if something goes wrong during the data retrieval (e.g., network issues, SharePoint API errors), the error is caught and logged instead of causing the entire app to crash.

Complete Example with Initialization

import { spfi, SPFx } from "@pnp/sp";
import "@pnp/sp/webs";
import "@pnp/sp/lists";

export default class MyWebPart extends BaseClientSideWebPart {

  protected async onInit(): Promise<void> {
    return this._getEnvironmentMessage().then(message => {
      this._environmentMessage = message;

      this.getListItems();
    });
  }

  protected async getListItems() {
    try {
      const sp = spfi().using(SPFx(this.context));
      const list = sp.web.lists.getByTitle("paises");

      const r = await list.select("Title")();
      console.log(r);
    } catch (error) {
      console.error("Error fetching list items:", error);
    }
  }
}

Conclusion

In this article, we explored how to use PnPjs and async/await in an SPFx web part to fetch data from a SharePoint list. By using PnPjs’ fluent API and JavaScript’s async features, you can easily integrate SharePoint operations in your SPFx solutions, making them responsive and easier to maintain.

Useful Links for Further Reading

Edvaldo Guimrães Filho Avatar

Published by

Categories:

Leave a comment