PnP People Picker Integration With SharePoint Framework (SPFx)

In this blog, we will learn to integrate PnP people picker control in SharePoint framework (SPFx).
 
People picker is used to select one or more entities. Pickers are used to manage a group of people by selecting from the list of people within a group. You can make use of "defaultSelectedUsers" property when some people are already been selected.
 
In this approach, we are restricting the people picker control to accept single value.
 
Below steps explain how to integrate people picker control in your spfx solution, and how to insert, retrieve people picker values in your spfx solution.
 
Steps Involved
 
Install "@pnp/spfx-controls-react" from node package manager as shown below.
  1. PS C:\XXXX\SPFxSolutions\SpFxRichTextEditor>npm install --save @pnp/spfx-controls-react  
Import "@pnp/spfx-controls-react/lib/PeoplePicker" to your tsx file.
  1. import { PeoplePicker, PrincipalType } from "@pnp/spfx-controls-react/lib/PeoplePicker";  
Declare the state variables as shown below.
  1. export interface IActionItemState {  
  2.     Assignee:number[];  
  3.     AssignedTo: string;  
  4. }  
Initialize the state values and bind the AssigneePicker function in form constructor as shown below. 
  1. constructor(props: IActionItemProps) {  
  2.    super(props);  
  3.    this._getAssigneePeoplePickerItems = this._getAssigneePeoplePickerItems.bind(this);
  4.    this.state = {  
  5.      Assignee:[],  
  6.      AssignedTo: ""  
  7.    };  
  8.  }  
Place the picker control in your render function as shown below.
  1. public render(): React.ReactElement<IActionItemProps> {  
  2.  return (  
  3.     <div>  
  4.                 <PeoplePicker  
  5.                     context={this.props.ctx}  
  6.                     titleText="Assigned To"  
  7.                     personSelectionLimit={1}  
  8.                     groupName={""// Leave this blank in case you want to filter from all users  
  9.                     showtooltip={false}  
  10.                     isRequired={true}  
  11.                     selectedItems={this._getAssigneePeoplePickerItems}  
  12.                     principalTypes={[PrincipalType.User]}  
  13.                     ensureUser={true}  
  14.                     defaultSelectedUsers={[this.state.AssignedTo]}  
  15.                   />  
  16.     </div>  
  17.  );  
  18.  }  
personSelectionLimit={1} -  restricts single user to be selected in the picker.
 
groupName = {""} - Leave this blank in case you want to filter from all the users, otherwise you can specify the group name, for eg : {"TestSharePointGroup"} 
 
Note
Make sure your context is defined in the "webpart.ts" file as shown below,
  1. public render(): void {      
  2.     const element: React.ReactElement<ISpFxRichTextEditorProps > = React.createElement(      
  3.       SpFxRichTextEditor,      
  4.       {      
  5.         spHttpClient: this.context.spHttpClient,        
  6.         siteUrl: this.context.pageContext.web.absoluteUrl,  
  7.         ctx: this.context,     
  8.       }      
  9.     );  
  10. }  
Render the selected pickers from the control as shown below. 
  1. /*Get People Picker selected value */  
  2.   private _getAssigneePeoplePickerItems(items: any[]) {  
  3.     try {  
  4.       this.state.Assignee.length = 0;  
  5.       let tempTeamAssArr = [];  
  6.       for (let item in items) {  
  7.         tempTeamAssArr.push(items[item].id);  
  8.       }  
  9.       this.setState({  
  10.         Assignee: tempTeamAssArr          
  11.       });  
  12.     } catch (error) {  
  13.       console.log("Error in _getAssigneePeoplePickerItems : ", error);  
  14.     }      
  15.   }  
To insert people picker values to sharepoint list follow the below steps.
 
Note
In the below example, I have assigned "this.state.Assignee[0]" to "AssignedToId". Usually, while inserting values to SharePoint people or group, you should assign values to its id instead of actual column name.
 
For Example:
 
If your column name in SharePoint list is "AssignedTo" then you have to pass values to its id like "AssignedToId".
 
If your column name in sharepoint list is "CopyTo" then you have to pass values to its id like "CopyToId" as shown below.  
  1. public addItems(requester: SPHttpClient, siteUrl: string, listName: string): Promise<any[]>{  
  2.         try{  
  3.           
  4.         const body: string = JSON.stringify({    
  5.         __metadata: { 'type''SP.Data.ActionItemFormListItem' },  
  6.                 AssignedToId: this.state.Assignee[0]          
  7.         });  
  8.               
  9.             return requester.post(`${siteUrl}/_api/web/lists/getbytitle('${listName}')/items`,  
  10.                 SPHttpClient.configurations.v1,  
  11.                 {  
  12.                     headers: {  
  13.                         "Accept""application/json;odata=verbose",  
  14.                         'Content-type''application/json;odata=verbose',  
  15.                         "odata-version"""  
  16.                     },  
  17.                     body: body   
  18.                 })  
  19.                 .then((response: SPHttpClientResponse) => {  
  20.                     return response.json();  
  21.                 })  
  22.                 .then((json) => {                      
  23.                     return(json);                       
  24.                 });  
  25.       
  26.         }catch(error){  
  27.             console.log("Error in addItems : ", error );  
  28.         }          
  29. }  
Usage
  1. this.addItems(this.props.spHttpClient, this.props.siteUrl, "ActionItemForm")  
  2.         .then((items: any[]) => {  
  3.           console.log("inserted sucessfully!!");  
  4. });  
To retrieve people picker values from sharepoint list and to bind values to people picker control follow the below steps.
  1. private async GetItem(itemID: string) {  
  2. try {  
  3.         var redirectionEmailURL = this.props.siteUrl + "/_api/web/lists/getbytitle('ActionItemForm')/Items?$filter=Id eq '" + itemID + "'&$select=AssignedTo/ID,AssignedTo/EMail,AssignedTo/Title&$expand=AssignedTo";  
  4.         const responseEmail = await this.props.ctx.spHttpClient.get(redirectionEmailURL, SPHttpClient.configurations.v1);  
  5.         const responseEmailJSON = await responseEmail.json();  
  6.         if (responseEmailJSON.value !== null) {  
  7.             var resultJSON = responseEmailJSON.value[0];  
  8.             if (resultJSON.AssignedTo != null) {  
  9.                 this.setState({ AssignedTo: resultJSON.AssignedTo.EMail });  
  10.             }              
  11.         }  
  12.     } catch (error) {  
  13.       console.log("Error in GetItem : " + error);  
  14.     }     
  15. }  
 Usage
 
parameter - Item Id has to be passed as a parameter to retrieve the specific item picker value. 
  1. this.GetItem(oListItemID);  
Please feel free to share your comments.
 
Hope this helps!!!!!