In most of the user request forms users wish to have some of the users details to be auto populated instead of entering manually to avoid human error and to maintain consistency. Especially the manger details, needs to be dynamically loaded from the User Profile.
In this article we will see how to auto populate current user in a people picker and their manger details in a Persona control. We will also see how to update manager details when user is changed in people picker. Thanks for Waldek for sp-starter-kit. It was so helpful.
What is used?
- PNP SPFX People picker reusable control
- Office UI Fabric Persona control
- PNPJS to get user profile details
- Graph API used to get user picture
Step 1: Create SPFX React webpart

Step 2: Add a People picker
I have used the PnP SPFX reusable react controls people picker. Install it with the below command into the project terminal
npm install @pnp/spfx-controls-react --save --save-exact
Open “.tsx” file and add this import statement just below the default imports
import { PeoplePicker, PrincipalType } from "@pnp/spfx-controls-react/lib/PeoplePicker";
Add the below people picker now into the method return statement
<PeoplePicker
context={this.props.context}
titleText="Requestor Name"
personSelectionLimit={1}
groupName={"Accounts Owners"} // Leave this blank in case you want to filter from all users
showtooltip={true}
isRequired={true}
//disabled={true}
selectedItems={this._getPeoplePickerItems}
showHiddenInUI={false}
principalTypes={[PrincipalType.User]}
resolveDelay={1000}
defaultSelectedUsers={this.state.curUserTitle} />

Step 3: Add Persona
To display the Manager photo and details I am going to use an Office UI Fabric Persona. You can still use another people picker and disable it to make it non editable. But I just want to try 😊 with Persona.
npm install office-ui-fabric-react
Add the below import statement just below the people picker import statement
import { Persona, PersonaSize, PersonaPresence } from 'office-ui-fabric-react/lib/Persona';
import { Stack } from 'office-ui-fabric-react/lib/Stack';
Add the below persona into the render method return statement
<div>
<p>Requestor Manager Name</p>
<Stack tokens={{ childrenGap: 10 }}>
<Persona imageUrl={this.state.image} text={this.state.managerName} secondaryText={this.state.mgrText} showSecondaryText={true} size={PersonaSize.size28} presence={PersonaPresence.none} />
</Stack>
</div>
Step 4: Declare State and Props
Create the below interface in the .tsx file just above the default class
export interface ISpfxpeoplepickerState{
managerName: string;
curUserLoginName: string;
curUserTitle: string[];
mgrimageUrl: string;
mgrText: string;
image: string;
}
Open “ISpfxpeoplepickerProps.ts” and replace it with below code
import { WebPartContext } from "@microsoft/sp-webpart-base";
import { MSGraphClient } from '@microsoft/sp-http';
export interface ISpfxpeoplepickerProps {
description: string;
context: WebPartContext;
graphClient: MSGraphClient;
}
We are ready now to load the data to the added controls.
Step 4: Load current user people picker
To get current user logged in I am going to use PnP SP JS and load it in people picker
npm install @pnp/sp
Add these import statement in .tsx file
import { sp } from "@pnp/sp";
import { CurrentUser } from '@pnp/sp/src/siteusers';
As we need to load current user on webpart load we will add code inside componentDidMount() method
public componentDidMount():void{
sp.web.currentUser.get().then((r: CurrentUser) => {
this.setState({ curUserLoginName: r['LoginName'], curUserTitle: [r['Title']]});
this._getManagerName(this.state.curUserLoginName);
});
}
Add these private methods inside the class to get and load manager details
//This will get ManagerName only by sending current user name
private _getManagerName(mgrUserName:string){
sp.profiles.getPropertiesFor(mgrUserName).then((profile: any) => {
var properties = {};
profile.UserProfileProperties.forEach(function(prop) {
properties[prop.Key] = prop.Value;
});
profile.userProperties = properties;
this._getManagerDetails(properties["Manager"]);
});
}
//To get more details about manager by sending manager name
private _getManagerDetails(user:string){
sp.profiles.getPropertiesFor(user).then((profile: any) => {
var properties = {};
profile.UserProfileProperties.forEach(function(prop) {
properties[prop.Key] = prop.Value;
});
profile.userProperties = properties;
var userName:string = properties['UserName'];
this.setState({ managerName: properties["PreferredName"], mgrText: properties["SPS-JobTitle"]});
this._getMgrPhoto(userName);
});
}
Step 5: Load manager picture using GraphClient
Open the .ts webpart file. Add this import statement
import { MSGraphClient } from '@microsoft/sp-http';
import { sp } from "@pnp/sp";
then add this onInit() method inside default class
private graphClient: MSGraphClient;
public onInit(): Promise<void> {
return new Promise<void>((resolve: () => void, reject: (error: any) => void): void => {
sp.setup({
spfxContext: this.context
});
this.context.msGraphClientFactory
.getClient()
.then((client: MSGraphClient): void => {
this.graphClient = client;
resolve();
}, err => reject(err));
});
}
public render(): void {
const element: React.ReactElement<ISpfxpeoplepickerProps > = React.createElement(
Spfxpeoplepicker,
{
description: this.properties.description,
context:this.context,
graphClient: this.graphClient,
}
);
ReactDom.render(element, this.domElement);
}
Why do we need to use Graph for this?
I tried using “sp.profiles.profileproperties” but for “PictureURL” is empty that’s because users profile picture is stored as “blob” which can be retrieved using Graph client. Graph Explorer is really amazing 😊
Open the .tsx file and add this private method inside the class
//To get manager picture from graph api
private _getMgrPhoto(mgrname:string){
console.log("ManagerName : "+mgrname);
this.props.graphClient
.api(`/users/${mgrname}/photo/$value`)
.responseType('blob')
.get((err: any, photoResponse: any, rawResponse: any) => {
const blobUrl = window.URL.createObjectURL(photoResponse);
this.setState({ image: blobUrl });
});
}
As our webpart need to connect to Graph api we need to add this “webApiPermissionRequests” in “package-solution.json” file
"webApiPermissionRequests": [{
"resource": "Microsoft Graph",
"scope": "User.ReadBasic.All"
}]
Step 6: Add people picker on change event
private _getPeoplePickerItems = (items: any[]):void => {
if(items && items.length){
sp.profiles.getPropertiesFor(items[0]['loginName']).then((profile: any) => {
//console.log(profile);
var properties = {};
profile.UserProfileProperties.forEach(function(prop) {
properties[prop.Key] = prop.Value;
});
profile.userProperties = properties;
this._getManagerDetails(properties["Manager"]);
});
}
}
Step 7: Deploy
gulp build
gulp bundle --ship
gulp package-solution –ship
Get the spfx package file from “sharepoint\solution” and upload it to your app catalogue site

Once deployed go to SharePoint Admin site –> API Management, and approve it.

We are ready to add our webpart into a SharePoint page. Really superb!!!…
My webpart loads like charm. It loads current user logged and the user’s manager. It also allows me to change the user in the people picker which relatively updates the manage details also in the persona.
