Fetching SharePoint List Items in an SPFx Application Customizer: The Reliable Solution

Introduction

When developing a SharePoint Framework (SPFx) Application Customizer, developers often need to fetch data from SharePoint lists. Initially, we attempted to use PnPjs to retrieve list items, but due to the context limitations in an Application Customizer (which differs from a Web Part context), we encountered persistent issues. After several failed attempts, we found that using HttpClient from @microsoft/sp-http provides a reliable solution.

This article will explain the issue we faced with PnPjs and present the working solution using HttpClient.

Why PnPjs Didn’t Work

PnPjs is a powerful library for interacting with SharePoint, but it assumes a Web Part context where sp.web is properly initialized. In an Application Customizer, we don’t have the same execution context as a Web Part, which caused the following issues:

  1. SPFI Instance Initialization Failure:
    • spfi().using(SPFx(context)) did not work correctly in the Application Customizer because context.pageContext.web was undefined.
  2. Cannot Read ‘lists’ of Undefined:
    • We attempted to access sp.web.lists.getByTitle(ListTitle).items(), but sp.web was not initialized correctly.
  3. SPFI Debugging Showed Empty Parent URL:
    • Debugging sp.web.toUrl() returned an empty string, indicating that the sp instance was not properly initialized.

After multiple failed attempts, we decided to use HttpClient instead of PnPjs, which worked perfectly.

The Working Solution: Using HttpClient

Step 1: Implement the API Call Function

Instead of relying on PnPjs, we use the HttpClient class provided by SPFx to fetch list items.

import { HttpClient, HttpClientResponse } from '@microsoft/sp-http';

export async function GetListItems(context: any, listTitle: string): Promise<any[]> {
    try {
        const siteUrl = context.pageContext.web.absoluteUrl;
        const apiUrl = `${siteUrl}/_api/web/lists/getbytitle('${listTitle}')/items`;
        console.log("API URL:", apiUrl);
        
        const response: HttpClientResponse = await context.httpClient.get(apiUrl, HttpClient.configurations.v1);
        
        if (!response.ok) {
            throw new Error(`Error fetching items: ${response.statusText}`);
        }
        
        const data = await response.json();
        return data.value || [];  // Return list items
    } catch (error) {
        console.error("Error fetching list items:", error);
        return [];
    }
}

Step 2: Call the Function from the Application Customizer

In your Application Customizer class, call GetListItems() and pass the SPFx context:

import { override } from '@microsoft/decorators';
import { Log } from '@microsoft/sp-core-library';
import { BaseApplicationCustomizer } from '@microsoft/sp-application-base';
import { GetListItems } from './GetListItems';

const LOG_SOURCE: string = 'CustomApplicationCustomizer';

export default class CustomApplicationCustomizer extends BaseApplicationCustomizer<any> {
  @override
  public async onInit(): Promise<void> {
    Log.info(LOG_SOURCE, `Initialized ${this.context.manifest.alias}`);
    
    const listTitle = "MySharePointList"; // Replace with your list title
    const items = await GetListItems(this.context, listTitle);
    
    console.log("Fetched items:", items);
  }
}

Why This Solution Works

Unlike PnPjs, which depends on an initialized SPFI instance, HttpClient directly communicates with the SharePoint REST API, ensuring:

Context is always valid

No dependency on Web Part execution context

Reliable and consistent data retrieval

Conclusion

If you are developing an SPFx Application Customizer and need to fetch SharePoint list data, avoid using PnPjs due to its reliance on the Web Part context. Instead, use HttpClient, which provides a reliable way to fetch list items without context-related issues.

This method ensures that your Application Customizer functions correctly across different environments, making it the preferred approach for SharePoint data retrieval.

Edvaldo Guimrães Filho Avatar

Published by