SharePoint framework React webpart CRUD operations

In this learning we will see how to make CRUD operations in a SharePoint framework React webpart. I have a list named “Projects” in my SharePoint Online site, we will learn how to

  • Create item
  • Read item
  • Update item
  • Delete item

Step 1: Create a basic (SPFx) SharePoint framework React webpart

Believe you have the required SPFx environment setup. Open your preferred command line tool and run the below command to create our basic webpart

md spfxReactCRUD
cd spfxReactCRUD
yo @microsoft/sharepoint

I have selected “React” as my framework for this tutorial. Once the webpart is created open the webpart project by using your preferred tool mine is visual studio code

Step 2: Add render method code to display buttons in the webpart

In this step we will add some buttons in the webpart as we need them to do the CRUD actions with them. Finally, the UI should look like this

Step 2a: Create an Interface “IListItem”

We need to add some code in .tsx file but before that we need to add 2 interfaces and will be referred in .tsx file later

Go to “components” folder right click “New file” and name it as “IListItem.ts”. Add the below code in it

export interface IListItem {  
    Title?: string;  
    Id: number;  
}

Step 2b: Create an Interface named “ISpfxReactCrudState”

Add another interface, create a new file named “ISpfxReactCrudState.ts” under components and add the below code in it

import { IListItem } from './IListItem';  
export interface ISpfxReactCrudState {  
  status: string;  
  items: IListItem[];  
}

Step 2c: Add buttons in code in “.tsx” file

Now open the webpart “SpfxReactCrud.tsx” file and add imports below the default references

import { ISpfxReactCrudProps } from './ISpfxReactCrudProps';
import { ISpfxReactCrudState } from './ISpfxReactCrudState'; 
import { IListItem } from './IListItem';  
import { SPHttpClient, SPHttpClientResponse } from '@microsoft/sp-http';

Add the below constructer code into the class file just above render method

constructor(props: ISpfxReactCrudProps, state: ISpfxReactCrudState) {  
    super(props);  
  
    this.state = {  
      status: 'Ready',  
      items: []
    }; 

Then add this render method which will add 4 buttons to my webpart. Its just html and css

public render(): React.ReactElement<ISpfxReactCrudProps> {  
    const items: JSX.Element[] = this.state.items.map((item: IListItem, i: number): JSX.Element => {  
      return (  
        <li>{item.Title} ({item.Id}) </li>  
      );  
    });  
  
    return (  
      <div className={ styles.spfxReactCrud }>  
        <div className={ styles.container }>  
          <div className={ styles.row }>  
            <div className={ styles.column }>  
              <span className={ styles.title }>Welcome to SharePoint!</span>  
              <p className={ styles.subTitle }>Customize SharePoint experiences using Web Parts.</p>  
              <p className={ styles.description }>{escape(this.props.listName)}</p>  
                
              <div className={`ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}`}>  
                <div className='ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1'>  
                  <a href="#" className={`${styles.button}`} onClick={() => this.createItem()}>  
                    <span className={styles.label}>Create item</span>  
                  </a>  
                  <a href="#" className={`${styles.button}`} onClick={() => this.readItem()}>  
                    <span className={styles.label}>Read item</span>  
                  </a>  
                </div>  
              </div>  
  
              <div className={`ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}`}>  
                <div className='ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1'>  
                  <a href="#" className={`${styles.button}`} onClick={() => this.updateItem()}>  
                    <span className={styles.label}>Update item</span>  
                  </a> 
                  <a href="#" className={`${styles.button}`} onClick={() => this.deleteItem()}>  
                    <span className={styles.label}>Delete item</span>  
                  </a>  
                </div>  
              </div>  
  
              <div className={`ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}`}>  
                <div className='ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1'>  
                  {this.state.status}  
                  <ul>  
                    {items}  
                  </ul>  
                </div>  
              </div>  
  
            </div>  
          </div>  
        </div>  
      </div>  
    );  
  }  

Then for now we will add the below empty methods ready to for each CRUD operation.

  private createItem(): void {   
  }    
  
  private readItem(): void {  
  }  
  
  private updateItem(): void {  
  }  
  
  private deleteItem(): void {  
  } 

Step 3: Test the webpart buttons and see how they look like.

Run “Gulp serve” in the command and insert the webpart in the local work bench page

Cool, we are ready with the controls rendering part. Now we need to explore on how to do CRUD operations

Step 4: Set the required properties

Update the props interface, by default its only with description field. We don’t need it.

Add the below code to set URL, Listname and SPHttpClient

import { SPHttpClient } from '@microsoft/sp-http'; 
export interface ISpfxReactCrudProps {
  listName: string;  
  spHttpClient: SPHttpClient;  
  siteUrl: string;
}

Now we need to update the code in “SpfxReactCrudWebPart.ts” file to fit in the above set parameters

SpfxReactCrud,
      {
        listName: "Projects",  
        spHttpClient: this.context.spHttpClient,  
        siteUrl: this.context.pageContext.web.absoluteUrl  
      }

Step 5: Add code logic to “Create item”

Open the “SpfxReactCrud.tsx” file and replace the “createItem” private method. The “spHttpClient” uses REST API to connect to the SharePoint site

private createItem(): void {  
    this.setState({  
      status: 'Creating item...',  
      items: []  
    });  
    
    const body: string = JSON.stringify({  
      'Title': `Item ${new Date()}`  
    });  
    
    this.props.spHttpClient.post(`${this.props.siteUrl}/_api/web/lists/getbytitle('${this.props.listName}')/items`,  
    SPHttpClient.configurations.v1,  
    {  
      headers: {  
        'Accept': 'application/json;odata=nometadata',  
        'Content-type': 'application/json;odata=nometadata',  
        'odata-version': ''  
      },  
      body: body  
    })  
    .then((response: SPHttpClientResponse): Promise<IListItem> => {  
      return response.json();  
    })  
    .then((item: IListItem): void => {  
      this.setState({  
        status: `Item '${item.Title}' (ID: ${item.Id}) successfully created`,  
        items: []  
      });  
    }, (error: any): void => {  
      this.setState({  
        status: 'Error while creating the item: ' + error,  
        items: []  
      });  
    });  
  }

Step 5: Test the final webpart with Create action

  • Now it’s time for us to hit Gulp serve, which opened the local workbench in which I clicked the “Create item” button gave me this error as it needs a SharePoint site and “Project” list in it

Error while creating the item: TypeError: Failed to fetch

  • So, leave the gulp serve running as it is, move to your SharePoint site where you have the “Projects” list and launch the SharePoint site workbench as below

https://yoursitename.sharepoint.com/sites/yoursubsitename/_layouts/15/workbench.aspx

  • Insert the webpart in it that SharePoint site workbench
  • Click the “Create item” button now, fantastic I got the success message saying item created

I could see my Projects list with the new item created in it. Cool !!!…

Thanks for your time reading my learnings.

Issues faced/Observations:

Property ‘items’ does not exist on type ‘Readonly<{}>’.ts(2339)

It’s because the “items” is declared inside the interface “ISpfxReactCrudState” but we have not added in the export class only “ISpfxReactCrudProps” and “{}” empty is available.

So, I added “ISpfxReactCrudState” as below and the error is gone