Category Archives: TypeScript

SPFx-People-Search

SharePoint/SPFx: Returning to Webpart Development Part #4 (with React Hooks)

Recently I was asked to develop a webpart for a modern SharePoint site. My first thoughts, where do I start; I haven’t done any webpart development for years? I would like to share my journey with you over the next few posts and hope my experience will help new and returning developers along the way.

In my previous post I covered:

In this post I will cover:

This article is different to its predecessors in the series, because I have published the SPFx-People-Search webpart solution to my GuiHub repository, I will be focusing on what I have found challenging about writing this webpart with React Hooks, SPFx and Microsoft Graph.

In the previous article I created the Project Folder Structure with stub files ready to add code. So now I can focus on creating the components such as the Service and User Interface. I deliberated on where to start, creating the Service layer or UI. Deciding to start with a service class called MSGraphService.ts and its corresponding interface.

Note: I have added a data JSON file, however I have more work to do before this can be used for testing in the local workbench.

Service Layer

The MSGraphService is based upon the Service Locator pattern which I took inspiration from an old colleague Vardhaman Deshpande who wrote this article. The MSGraphService files are located here:

Having decided on this pattern and how to implement it, the other challenges I had with the Microsoft Graph API included:

Microsoft Graph User Photo

What to do with the data returned by Microsoft Graph User Photo endpoint. With the lack of documentation, the Graph Explorer is great, but it still took a bit of work to figure out what to do with “Blob Strings” …

Microsoft Graph Explorer Me/User Photo
https://developer.microsoft.com/en-us/graph/graph-explorer?request=me%2Fphoto%2F%24value&method=GET&version=v1.0

See the getUserPhoto() function located within MSGraphService.ts

User Presence

What the different User Presence options are: User may display…? Again, the Graph Explorer was a great help, it went a long way to making up for the lack of documentation.

Microsoft Graph Explorer Me/User Presence
https://developer.microsoft.com/en-us/graph/graph-explorer?request=me%2Fpresence&method=GET&version=beta

See the getUserPresence() function located within MSGraphService.ts and the implementation within ResultCard.tsx

Configure the API permissions requests

This time I can praise the documentation by Microsoft: “To consume Microsoft Graph or any other third-party REST API, you need to explicitly declare the permission requirements from an OAuth perspective in the manifest of your solution.” For more information see https://docs.microsoft.com/en-us/sharepoint/dev/spfx/use-aad-tutorial#configure-the-api-permissions-requests

And my working example of the package-solution.json can be found here: https://github.com/sionjlewis/SPFx-People-Search/blob/main/config/package-solution.json

User Interface

To keep things simple, I kept the PeopleSearchWebPart.ts webparts “main/entry” class, created by the SPFx Yeoman scaffold, pretty much “as is”. Converting this class to React Hook seemed to be more hassle that it was worth.

Using React Hooks with the SPFx framework

So unlike all the React.JS Hook Documentation, I was unable to implement a basic function, but instead I found I needed to write something similar to the following:

export const PeopleSearch: React.FunctionComponent<IPeopleSearchProps> = (props) => { 
    … 
};

Writing the Hooks

Having organised the components into a Project Folder Structure, I started at the top:

  1. Added references and initiated object to PeopleSearchWebPart.ts and passed them on to PeopleSearch.tsx
  2. Updated the IPeopleSearchProps.tsx interface and added each of the “Wrapper” Hooks to the return statement
  3. Focusing on the ResultWrapper, I added the “useState” and “useEffect” Hooks to handle the getFilteredUsersExpanded() data, which I then “mapped” instances of the ResultCard.tsx
  4. Before focusing on details such as User Presence and User Photo, I output the “raw” User data to the user interface from the return statement. I used this technique to confirm that the service layer was connecting to and returning the data as expected

I continued on with this process of working until I “finished” the Results components and then moved onto the Footer and Search components.

You may have noticed that I have not started on the filter components as my strategy is to get something working as quickly as possible, with the following goals:

  • Enables demos and feedback loop to start earlier
  • Test the API(s) to confirm that they work as expected (or documented) and update our strategy if they don’t

Other Stuff

underscore.js vs Lodash

Back in my “JavaScript” days I was a big fan of underscore.js, so I tried it within this project, however I found the library too cumbersome to import and so I ended up replacing it with Lodash which seems to play better with TypeScript.

Conclusion

I am now a self-confessed fan of React Hooks and have really enjoyed the process of building this webpart. As with any new development technique or process, I will find better ways of doing things as I do more, but I like how clean the code looks and reckon the modularity will make the solution so much easier to support.

SharePoint/SPFx: Returning to Webpart Development Part #3 (with React Hooks)

Recently I was asked to develop a webpart for a modern SharePoint site. My first thoughts were; where do I start; I haven’t done any webpart development for years? I would like to share my journey with you over the next few posts and hope my experience will help new and returning developers along the way.

In my previous post I covered:

In this post I will cover:

Recommended Reading

The official React website has some fantastic documentation and to avoid duplicating what they have already published I would recommend reading the “Thinking in React” article before we move on. I found the section “Step 2: Building A Static Version In React” particularly useful to kick-off the build of this webpart.

Using React Hooks with the SPFx Framework

The first thing I did was to import the React module using following statement:

import React, { useState, useEffect } from 'react';

When I tried to build the project, I received the following error:

Module '"c:/.../SJLewis.SPFx.Webparts.People/node_modules/@types/react/index"' can only be default-imported using the 'allowSyntheticDefaultImports' flagts(1259)
index.d.ts(46, 1): This module is declared with using 'export =', and can only be used with a default import when using the  'allowSyntheticDefaultImports' flag.

Plus, the React and ReactDom import statements are underlined in red:

React and ReactDom import statement is underlined in red

What is allowSyntheticDefaultImports? It allows default imports from modules with no default export and it does not affect code emitted, it is just typechecking.

How to enable allowSyntheticDefaultImports

Open the tsconfig.json file and add the following code to the “compilerOptions” section:

"allowSyntheticDefaultImports": true

Your tsconfig.json file should look something like this:

allowSyntheticDefaultImports

And now TypeScript is happy…

React and ReactDom import statement are validated

Before moving on to the next step, let’s build the project and commit your changes to source control (just in case we break the project later).

Installing additional NPM packages

We don’t always know all of the packages we want to use upfront, however I like to add what I can upfront. For this example, I am going to add the following npm packages to my project. Enter the commands into the VS Code Terminal window:

And finish by doing some “housekeeping” and confirming that the project builds:

gulp clean
npm shrinkwrap
gulp build

Project Folder Structure

I like to start by creating a folder structure based upon the Components and Services listed within my wire-frame(s) and components list.

People Search Wire-Frame

Component List

Component NameData SourceExpected ResultsComponent Actions
Search Wrapper 
Search BoxGraph UsersZero to more itemsFilter
Search Clear Clear data & filters
Filter WrapperGraph UsersZero to more items
Filter Combo-boxGraph UsersZero to more itemsFilter
Filter Auto-suggestGraph UsersZero to more itemsFilter
Result WrapperGraph UsersZero to more items
Result CardGraph UserOne itemDisplay
Result User PhotoGraph User PhotoOne itemDisplay
Result User PresenceGraph User PresenceOne itemDisplay
Result User ContactGraph UserOne itemDisplay
Footer WrapperGraph UsersZero to more itemsDisplay

Component Folder Structures

Starting with components, add the following folders under this path:

“~\src\webparts\peopleSearch\components\”

  • filters
  • results
  • search

Next, add blank/empty .TSX files for each component:

~\src\webparts\peopleSearch\components\filters\

  • FilterWrapper.tsx
  • FilterComboBox.tsx
  • FilterAutoSuggest.tsx

~\src\webparts\peopleSearch\components\footer\

  • FooterWrapper.tsx

~\src\webparts\peopleSearch\components\results\

  • ResultWrapper.tsx
  • ResultCard.tsx
  • ResultUserPhoto.tsx
  • ResultUsrPresence.tsx      Not required / built into Persona (Office UI Fabric) control
  • ResultUserContact.tsx

~\src\webparts\peopleSearch\components\search\

  • SearchWrapper.tsx
  • SearchBox.tsx
  • SearchClear.tsx

Even thought these files are empty the project should build without any issues, I still like to build the project after every major change I make.

<em>gulp build</em>

Note: “~\” represents the project’s root folder.

Service, Models & Data Folder Structures

I am going to create the folder structure which will be used by the Service, Models & Data files. Start by adding the following folders under this path: “~\src\”

  • data
  • models
  • services

I have not planned exactly what will be created, but here is an overview as to what will go where:

  • The Data folder will contain .JSON files, these will contain mock data for testing the webpart using the local work bench
  • The Models folder will contain .TS files, which will describe the structure of the data respective of where it is stored or accesses from.
  • The Service folder will contain .TS files and classes that will represent the services and will retrieve data either from the mock or live data sources.

Next Steps

Now that I have my project structure laid out, I can focus on creating either the Data & Services or the Components & User Interface. Neither option is wrong, however, because I know more about the User Interface than the Services, that is where I will begin for my next post.

Tip: If you cannot decide on which order to build your webpart(s) take a look at the “Thinking in React” article, you may also find the section “Step 2: Building A Static Version In React” useful.