Reputation: 19
I am developing an SPFx WebPart using PnPjs to upload files to a SharePoint document library.
However, when attempting to upload a file, I receive the following error:
Upload failed: TypeError: context.pageContext is undefined
Alternatively, I sometimes get a 403 error:
Upload failed: Error: Error making HttpClient request in queryable [403] ::> {"odata.error":{"code":"-2147024891, System.UnauthorizedAccessException","message":{"lang":"de-DE","value":"Access Denied."}}}
I have checked whether context.pageContext is available by logging console.log(this.context), but it seems to be undefined. I also ensured that my PnPjs instance is initialized correctly using getSP(this.context) inside onInit(), and logging console.log(this.sp) confirms that a valid PnPJS instance is created. Additionally, I verified whether my user has write permissions for the SharePoint document library, as I suspect missing permissions could be causing the issue. However, I am unsure if a lack of permissions would specifically result in context.pageContext being undefined. I tested the WebPart both in the local workbench and in the online workbench (https://aivdev.sharepoint.com/%5C_layouts/15/workbench.aspx), but the issue persists in both environments.
Why is context.pageContext
undefined?
ProgressReportWebPart.ts
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import { IProgressReportProps } from './components/IProgressReportProps';
import ProgressReport from './components/ProgressReport';
import { getSP } from '../../pnpjsConfig';
import { SPFI } from "@pnp/sp";
export default class ProgressReportWebPart extends BaseClientSideWebPart<IProgressReportProps> {
private sp: SPFI;
public render(): void {
const element: React.ReactElement<IProgressReportProps> = React.createElement(
ProgressReport,
{
context: this.context // 🔹 Passing the context
}
);
ReactDom.render(element, this.domElement);
}
public async onInit(): Promise<void> {
await super.onInit();
this.sp = getSP(this.context);
}
}
ProgressReport.tsx
import * as React from "react";
import { WebPartContext } from "@microsoft/sp-webpart-base";
import PnpFileUpload from "./PnpFileUpload";
export interface IProgressReportProps {
context: WebPartContext;
}
const ProgressReport: React.FC<IProgressReportProps> = ({ context }) => {
return (
<div>
<h1>📊 Progress Report</h1>
<PnpFileUpload context={context} />
</div>
);
};
export default ProgressReport;
PnpFileUpload.tsx:
import * as React from "react";
import { WebPartContext } from "@microsoft/sp-webpart-base";
import { SPFI } from "@pnp/sp";
import "@pnp/sp/files";
import "@pnp/sp/folders";
import { getSP } from "../../../pnpjsConfig";
export interface IPnpFileUploadProps {
context: WebPartContext;
}
export interface IPnpFileUploadState {
selectedFile: File | null;
}
export default class PnpFileUpload extends React.Component<IPnpFileUploadProps, IPnpFileUploadState> {
private sp: SPFI;
constructor(props: IPnpFileUploadProps) {
super(props);
this.sp = getSP(props.context);
this.state = {
selectedFile: null,
};
this.handleFileChange = this.handleFileChange.bind(this);
this.filesave = this.filesave.bind(this);
}
handleFileChange(event: React.ChangeEvent<HTMLInputElement>) {
const file = event.target.files?.[0] || null;
this.setState({ selectedFile: file });
}
async filesave() {
const { selectedFile } = this.state;
if (!selectedFile) {
console.log("No file selected");
return;
}
try {
const folderUrl = "/sites/aivdev/ProgressReport";
const fileAddResult = await this.sp.web.getFolderByServerRelativePath(folderUrl)
.files.addUsingPath(selectedFile.name, selectedFile, { Overwrite: true });
console.log("File Uploaded:", fileAddResult);
} catch (error) {
console.error("Upload failed:", error);
}
}
public render(): React.ReactElement<IPnpFileUploadProps> {
return (
<div>
<input type="file" onChange={this.handleFileChange} />
<button onClick={this.filesave}>Upload File</button>
</div>
);
}
}
Upvotes: 0
Views: 25