Building a SPFx Web Part: Fetching Data with PnP JS and Microsoft Graph

In this tutorial, we’ll create a SharePoint Framework (SPFx) web part that integrates PnP JS and Microsoft Graph to display user data and items from a SharePoint list. We’ll use React and TypeScript, focusing on class-based components.

Objective

By the end of this article, you will know how to:

  1. Fetch user data from Microsoft Graph.
  2. Retrieve items from a SharePoint list using PnP JS.
  3. Render this data in an SPFx web part.

The Complete Code

Here’s the full implementation of the SPFx web part:

import * as React from "react";
import type { IGraphBasicoProps } from "./IGraphBasicoProps";
import "@pnp/graph/users"; // Import PnP Graph

// Interface for list items
interface listItems {
  Title: string;
  Description: string;
}

// State interface for the component
interface IGraphBasicoState {
  items: listItems[]; // SharePoint list items
  meGraph: any | null | undefined; // Microsoft Graph user data
}

export default class GraphBasico extends React.Component<IGraphBasicoProps, IGraphBasicoState> {
  constructor(props: IGraphBasicoProps) {
    super(props);

    // Initializing state
    this.state = {
      items: [],
      meGraph: null,
    };
  }

  // Fetching data when the component mounts
  public async componentDidMount(): Promise<void> {
    try {
      // Fetch SharePoint list items using PnP
      const items = await this.props.sp.web.lists.getByTitle("GraphTest").items();

      // Fetch Microsoft Graph user information
      const me = await this.props.graph.me();

      // Update state with fetched data
      this.setState({
        items,
        meGraph: me,
      });
    } catch (error) {
      console.error("Error fetching data:", error);
    }
  }

  public render(): React.ReactElement<IGraphBasicoProps> {
    const { items, meGraph } = this.state;

    return (
      <div>
        <h1>User Data</h1>
        {meGraph ? (
          <p>Name: {meGraph.displayName}</p>
        ) : (
          <p>Loading user data from Microsoft Graph...</p>
        )}

        <h1>List Items</h1>
        {items.length > 0 ? (
          items.map((item, index) => (
            <div key={index}>
              <hr />
              <div>Title: {item.Title}</div>
              <div>Description: {item.Description}</div>
              <hr />
            </div>
          ))
        ) : (
          <p>Loading list items from SharePoint...</p>
        )}
      </div>
    );
  }
}


Step-by-Step Explanation

1. Setting Up State

We define the component’s state using an interface:

interface IGraphBasicoState {
  items: listItems[];
  meGraph: any | null | undefined;
}

  • items: Stores list items from SharePoint.
  • meGraph: Stores user data fetched from Microsoft Graph.

2. Fetching Data

We use the componentDidMount lifecycle method to fetch data as soon as the component loads.

Fetching List Items from SharePoint

const items = await this.props.sp.web.lists.getByTitle("GraphTest").items();

  • This line uses PnP JS to fetch items from the GraphTest list.
  • Ensure that the list name matches your SharePoint list name.

Fetching User Data from Microsoft Graph

const me = await this.props.graph.me();

  • This fetches details about the current user from Microsoft Graph.

Updating State

Once the data is fetched, we update the state:

this.setState({
  items,
  meGraph: me,
});

3. Rendering Data

Rendering User Information

We conditionally render the user’s name:

{meGraph ? (
  <p>Name: {meGraph.displayName}</p>
) : (
  <p>Loading user data from Microsoft Graph...</p>
)}

Rendering SharePoint List Items

Using .map(), we iterate over the list items:

{items.map((item, index) => (
  <div key={index}>
    <div>Title: {item.Title}</div>
    <div>Description: {item.Description}</div>
  </div>
))}


What You’ll See

User Data

Once fetched, the user’s name is displayed:

Name: John Doe

If the data is still loading, a placeholder message appears:

Loading user data from Microsoft Graph...

List Items

The items from the SharePoint list appear as a list:

Title: Task 1
Description: Complete the project
---
Title: Task 2
Description: Review the report

While loading:

Loading list items from SharePoint...


Prerequisites

  1. SPFx Setup
    Ensure your SPFx project is configured. Use the following command to scaffold a React-based SPFx web part:
yo @microsoft/sharepoint

  1. Install PnP JS
    Install the required PnP libraries:
npm install @pnp/sp @pnp/graph

  1. Microsoft Graph Permissions
    In Azure AD, grant appropriate permissions to the SPFx web part for Microsoft Graph (e.g., User.Read).
  2. Configure PnP JS
    In your web part’s onInit method, configure PnP:
import { sp } from "@pnp/sp";
import { graph } from "@pnp/graph";

public async onInit(): Promise<void> {
  sp.setup(this.context);
  graph.setup(this.context);
}


Error Handling

Always handle errors during data fetching:

catch (error) {
  console.error("Error fetching data:", error);
}

This ensures that your app remains functional, even if a fetch request fails.


Conclusion

This SPFx component demonstrates how to combine the power of React, PnP JS, and Microsoft Graph to create dynamic web parts. By following this tutorial, you can build robust SPFx solutions that integrate SharePoint and Microsoft 365 services.

For further exploration:

Edvaldo Guimrães Filho Avatar

Published by