Harsha Vardhini

Mar 16, 20191 min

SPFx - SP PnP JS not working on modern pages

When you are working with Spfx you may choose @pnp/sp library as they provides a fluent API to make building your REST queries intuitive and supports batching and caching. It is very easy to use. You can find the examples here.

I have used the below snippet to get items from the list:

import pnp from "sp-pnp-js";

pnp.sp.web.lists.getByTitle("Task").select("Title", "ID").items.get().then((items: any[]) =>

this.setState({

listItems: items

)};

});

After building my SPFX webpart, when I deployed in classic page, it worked as expected. But when I added the same webpart in modern page, I got the following error.

GET https://mysite.sharepoint.com/SitePages/_api/web 404 (Not Found)

The URL contains /SitePages that shouldn't be included.

This issue occurs as the pnp js api didn’t get the SharePoint context. So this is how I fixed the issue:

In the props file, add the webpartcontext prop:

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

export interface IMyListTrainingMasterProps {

description: string;

context:WebPartContext;

}

In the webpart.ts file add the newly created prop and initialize it this.context to get the SharePoint context:

public render(): void {

const element: React.ReactElement<IMyListTrainingMasterProps >= React.createElement(

MyListTrainingMaster,

{

description: this.properties.description,

context: this.context

}

);

Now the final step. In your component (.tsx file), get the context of the web from the context prop which we created as below:

let web = new Web(this.props.context.pageContext.web.absoluteUrl);

web.lists.getByTitle("Task").select("Title", "ID").items.get().then((items: any[]) => {

this.setState({

listItems: items

});

}

});

    1