Transforming a Standard SPFx Web Part into a CRUD Functionality with PnPjs
In this article, we will explore how to transform a standard SharePoint Framework (SPFx) web part into a functional CRUD (Create, Read, Update, Delete) application using PnPjs. We will demonstrate how to create the web part, implement the necessary functionalities, and ensure that everything is encapsulated within a single TypeScript file.
Overview of the Code Structure
1. Web Part File: PnPjsCrudDemo2TrasPorteFuncaoWebPart.ts
This file serves as the main entry point for our web part. Here’s a breakdown of its key components:
import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import { IPropertyPaneConfiguration, PropertyPaneTextField } from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import { spfi, SPFx } from "@pnp/sp";
import "@pnp/sp/webs";
import "@pnp/sp/lists";
import "@pnp/sp/items";
import PnPjsCrudDemo2TrasPorteFuncao from './components/PnPjsCrudDemo2TrasPorteFuncao';
import { IPnPjsCrudDemo2TrasPorteFuncaoProps } from './components/IPnPjsCrudDemo2TrasPorteFuncaoProps';
export interface IPnPjsCrudDemo2TrasPorteFuncaoWebPartProps {
description: string;
}
export default class PnPjsCrudDemo2TrasPorteFuncaoWebPart extends BaseClientSideWebPart<IPnPjsCrudDemo2TrasPorteFuncaoWebPartProps> {
public sp: any;
public onInit(): Promise<void> {
return super.onInit().then(_ => {
this.sp = spfi().using(SPFx(this.context));
});
}
public render(): void {
const element: React.ReactElement<IPnPjsCrudDemo2TrasPorteFuncaoProps> = React.createElement(
PnPjsCrudDemo2TrasPorteFuncao,
{
addItem: this.addItem.bind(this),
deleteItem: this.deleteItem.bind(this),
getItems: this.getItems.bind(this),
updateItem: this.updateItem.bind(this),
sp: this.sp
}
);
ReactDom.render(element, this.domElement);
}
private async addItem(sp: any) {
try {
const list = sp.web.lists.getByTitle("MyList");
const result = await list.items.add({
Title: "New Item",
Description: "This is a new item"
});
console.log("Item added:", result);
} catch (error) {
console.error("Error adding item:", error);
}
}
private async getItems(sp: any) {
const items = await sp.web.lists.getByTitle("MyList").items.select("Title", "Description")();
console.log("Items retrieved:", items);
}
private async updateItem(sp: any, itemId: number) {
try {
const item = await sp.web.lists.getByTitle("MyList").items.getById(itemId).update({
Title: "Updated Title",
Description: "Updated Description"
});
console.log("Item updated:", item);
} catch (error) {
console.error("Error updating item:", error);
}
}
private async deleteItem(sp: any, itemId: number) {
try {
await sp.web.lists.getByTitle("MyList").items.getById(itemId).delete();
console.log(`Item with ID ${itemId} deleted`);
} catch (error) {
console.error("Error deleting item:", error);
}
}
protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
return {
pages: [
{
header: {
description: 'Web Part Configuration'
},
groups: [
{
groupName: 'Settings',
groupFields: [
PropertyPaneTextField('description', {
label: 'Description'
})
]
}
]
}
]
};
}
}
Key Features:
- PnPjs Initialization: We initialize PnPjs with the current SPFx context in the
onInitmethod, allowing us to interact with SharePoint lists and items seamlessly. - CRUD Functions:
- Add Item: This function adds a new item to the “MyList” SharePoint list with a predefined title and description.
- Get Items: This function retrieves all items from the “MyList” SharePoint list, selecting only the title and description fields.
- Update Item: This function updates an existing item in the “MyList” SharePoint list by its ID, changing its title and description.
- Delete Item: This function deletes an item from the “MyList” SharePoint list based on its ID.
2. Properties File: IPnPjsCrudDemo2TrasPorteFuncaoProps.ts
This interface defines the properties that are passed to the React component.
export interface IPnPjsCrudDemo2TrasPorteFuncaoProps {
addItem: any,
deleteItem: any,
getItems: any,
updateItem: any,
sp: any
}
3. React Component: PnPjsCrudDemo2TrasPorteFuncao.tsx
This component contains the UI and triggers the CRUD operations through buttons.
import * as React from 'react';
import type { IPnPjsCrudDemo2TrasPorteFuncaoProps } from './IPnPjsCrudDemo2TrasPorteFuncaoProps';
export default class PnPjsCrudDemo2TrasPorteFuncao extends React.Component<IPnPjsCrudDemo2TrasPorteFuncaoProps, {}> {
public render(): React.ReactElement<IPnPjsCrudDemo2TrasPorteFuncaoProps> {
const { addItem, deleteItem, getItems, updateItem, sp } = this.props;
return (
<div>
<button onClick={() => addItem(sp)}>Add Item</button>
<button onClick={() => getItems(sp)}>Get Items</button>
<button onClick={() => updateItem(sp, 1)}>Update Item</button>
<button onClick={() => deleteItem(sp, 1)}>Delete Item</button>
</div>
);
}
}
Key Features:
- Button Actions: Each button triggers the corresponding CRUD function when clicked, demonstrating how easy it is to interact with SharePoint data.
Conclusion
In this article, we demonstrated how to transform a standard SPFx web part into a functional CRUD application using PnPjs. By following the provided code structure, you can easily modify and extend this example to fit your specific requirements. This approach not only helps in managing SharePoint data effectively but also promotes a clean and maintainable codebase.
Example Code
Here is the complete example code for reference:
PnPjsCrudDemo2TrasPorteFuncaoWebPart.ts
// Complete code as shown earlier
IPnPjsCrudDemo2TrasPorteFuncaoProps.ts
// Complete code as shown earlier
PnPjsCrudDemo2TrasPorteFuncao.tsx
// Complete code as shown earlier
This example will serve as a template for creating additional web parts that require CRUD functionalities using PnPjs. By adapting this model, you can develop various applications tailored to your needs

Leave a comment