Skywalker3171

Developer´s SharePoint blog (SharePoint, Workflows, Apps, Document Management Systems, etc…)

Posts Tagged ‘CRUD’

A simple SpFx CRUD WebPart with PnP V3

Posted by skywalker3171 on December 28, 2022

In this blogpost we will walktrough the steps of creating a simple SpFx WebParts that executes all the CRUD operations and offers a basic UI. First we need to execute the steps of creating a new webpart with Yeoman, call the project spfx-pnp-js-crud.

If you get the same picture – Generator 1.16.1 – make sure to downgrade to 1.16.0 in your projects package.json file, wherever you see 1.16.1. At the time of writing this blogpost there is an error in 1.16.1 that prevents the webpart from working correctly.

Now follow the steps in Microsoft learn Build your first SharePoint client side webpart and check you Webpart is functioning correctly with the workbench.

The toolchain configuration used in this example:

  • Node version: v.14.15.1
  • NPM version: 6.14.8
  • SharePoint framework version: 1.16.0
  • PnP version: 3.9.0

The UI in this post will be developed with Office-Fabric, although fluent is better and will be included in a future post. As a React newbie I chose to split my webpart in three components:

  • HeroApp is the container App for the Other two components
  • HeroEdit is the Edit form for the three fields and has a submit button
  • HeroLine prints out a line for each List item and contains two buttons

For each of the three components the Props are defined in a seperate interface file. HeroEditProps and HeroLineProps declare their add, change and delete functions which are defined in HeroApp and passed down.

IResponseHero.ts contains the structure for an item that is returned from a SharePoint list, Demolist. Please note that the interfaces are plain Typescript and the components are TSX. A TSX file is a TypeScript (.TS) file written using JSX React syntax.

Let’s see how these components play together.

  • PnPjsExampleWebPart is the main webpart that is defined as an entrypoint in config.json. It’s main task is to instantiate the HeroApp class, read configurable data from the webpart property pane and pass these parametrs on to the classes.
  • HeroApp defines the four function Create, Readall, Update and Delete. All these functions are easily understandable since they make use of PnP V3. All you have to do is instantiate _sp in the constructor: this._sp = getSP(); The render method creates an instance of HeroEdit and one instance for every element of the List.
  • HeroEdit receives the OnClick funtion from above and executes it when the button is clicked. The action will decide if it is in an ‘add’ or ‘change’ state. Since the parameters/data that are passed up are using the components state, this state had to be altered using a separate change method for each field. The change method also had to be bound.
  • HeroLine receives the delete and the change function from above. Both functions need to be bound in the constructor. For displaying the data in the HeroLine component it is sufficient to use the properties, no state.

All data and functions are kept in the uppermost component and passed down to HeroEdit and HeroLine, which take care of the diplay and trigger the respective actions.

As an example of how PnP works, we will have a look at _readAllHeroItems(). _sp has already been defined in the constructor and with that we are connected to the local SharePoint site which must contain a list called ‘Demolist’. Instead of OData or Axios we use the PnP call to get our four fields.The response is then mapped into an array of IResponseHeroItem. These items are then pushed into the state. With the state being changed, a new render is instantly triggered.

private _readAllHeroItems = async (): Promise<void> => {
    try {
      //const spCache = spfi(this._sp).using(Caching(cacheProps));
      //this._sp.using(Caching(cacheProps));

      console.log('started _readAllHeroItems');
      const response: IResponseHeroItem[] = await this._sp.web.lists
        .getByTitle("Demolist")
        .items
        .select("Id", "Title", "Color", "Power")();

      // use map to convert IResponseItem[] into our internal object IFile[]
      const items: IResponseHeroItem[] = response.map((item: IResponseHeroItem) => {
        return {
          ID: item.ID,
          Title: item.Title || "Unknown",
          Color: item.Color,
          Power: item.Power
        };
      });

      // Add the items to the state
      this.setState({ heroItems: items });
      console.log('state set');
    console.log('state itmes: '+ this.state.heroItems.length);
    } catch (err) {
      Logger.write(`${this.LOG_SOURCE} (_readAllFilesSize) - ${JSON.stringify(err)} - `, LogLevel.Error);
    }
  }

The other three PnP methods are even easier to unterstand, just use:

  • item.add()
  • items.getById(ID).update()
  • items.getById(ID).delete()

The necessary state change for all four methods is handled by another method, that executes the state change and then calls the PnP methods.

To have a working webpart the SharePoint List (Demolist) must have three single line textfields called Title, Color and Power.

Checkout the complete example on github: Skywalker3171 spfx-pnp-js-crud.

Posted in Apps, SharePoint Online, Walkthrough | Tagged: , , , | Leave a Comment »