-
Notifications
You must be signed in to change notification settings - Fork 310
Unable to access SPFi object after partial page reload #3334
Copy link
Copy link
Open
Description
Major Version
4.x
Minor Version Number
4.18.0
Target environment
SharePoint Framework
Additional environment details
Web parts running from app catalog in standard M365 tenant
Expected or Desired Behavior
The desired behavior is to use the SPFi object without reinitializing the context. The operation is usually retrieving items from a list. But it could also be getting info about the web, retrieving data from another site, etc.
Observed Behavior
I get the error Cannot read properties of undefined (reading 'web') when the web part runs again after a partial page reload. In my example I'm getting the web, but it was originally found trying to access sp.web.lists.
Steps to Reproduce
- Setup a HelloWorld web part as described below.
- Add this to the home page of a communication site
- Setup another page in the comms site, with a link in the navigation
- Load home page, allow web part to render (works this time)
- Use navigation to go to other page
- Use navigation to return to the home page
- Observe error
Create a HelloWorld web part that initializes a common SPFi object via a centralized helper.
Web part init:
protected onInit(): Promise<void> {
getSP(this.context);
return this._getEnvironmentMessage().then(message => {
this._environmentMessage = message;
});
}
Centralized SPFi init:
/* eslint-disable no-var */
import { WebPartContext } from "@microsoft/sp-webpart-base";
// import pnp and pnp logging system
import { ISPFXContext, spfi, SPFI, SPFx as spSPFx } from "@pnp/sp";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import "@pnp/sp/batching";
var _sp: SPFI;
export const getSP = (context?: WebPartContext): SPFI => {
if (_sp === undefined || _sp === null) {
//You must add the @pnp/logging package to include the PnPLogging behavior it is no longer a peer dependency
// The LogLevel set's at what level a message will be written to the console
_sp = spfi().using(spSPFx(context as ISPFXContext));
}
return _sp;
};
Rendered component:
(error occurs on line 14)
import * as React from 'react';
import type { IPnPjsWebPartProps } from './IPnPjsWebPartProps';
import { useEffect, useState } from 'react';
import { getSP } from '../../../helpers/pnpjs-config';
const PnPjsWebPart: React.FunctionComponent<IPnPjsWebPartProps> = (props: IPnPjsWebPartProps) => {
const [message, setMessage] = useState<string>('Initial value, stil loading...');
useEffect(()=>{
// eslint-disable-next-line @typescript-eslint/no-floating-promises
(async ()=>{
try {
const sp = getSP();
const web = await sp.web(); // errors here on partial page reload
console.log(web);
setMessage('Got the web without an error! Hurrah!')
} catch (e) {
console.error('Error getting web :\'(', e);
setMessage((e as Error).message);
}
})();
},[])
return (
<section>
<div>{message}</div>
</section>
);
}
export default PnPjsWebPart;
Reactions are currently unavailable