Using the Graph API to Create a ‘Person’ Web Part

Business use case: when someone performs a search on our intranet and finds a person result, we want to show that person on a full-width web page– in a format customized to our needs. We don’t want to use Delve, and in some cases, we want to show more than the out-of-the-box ‘card’ experience for viewing people. To do this, we will tap into the Graph API.

Here is what the finished product looks like:

Our person details page also comes with an organization chart. This is fully interactive, allowing users to walk up and down and laterally throughout the organization.

We accomplish this using the Graph API. Using the Graph Explorer, I can see how to form the REST call to get my manager’s direct reports. This is demonstrated in the video below.

In the video, I have not signed in to Graph Explorer with my corporate account, so I am getting mock data provided by Microsoft. You can do the same thing!

Next, we create a new React web part. In the componentDidMount() method of the TSX file, we get the user’s ID (passed into the page in the query string) and then call the getUser() method.

  
public componentDidMount()
{ 
      let uId = window.location.href.toLowerCase()
          .split("pid=")[1];   
      this.getUser(uId);         
}

In the getUser() method, we make the call to the Graph API. After the user’s information is retrieved, we use setState() to set the state of the ‘user’ component – so that we can display that person’s information.

private getUser(uId: string){   
	this.props.context.graphHttpClient
	.get(`v1.0/users/`+ uId +`?$select=id,businessPhones,
	   displayName,givenName,jobTitle,mail,mobilePhone,
	   officeLocation,preferredLanguage,surname,
	   userPrincipalName,department,companyName`, 
 	   GraphHttpClient.configurations.v1)
	.then((response: HttpClientResponse) => {
		if (response.ok) {
			return response.json();
		}
	}).then((user:any)=>{      
		this.setState({user:user});
	});
}

As a result of using this.setState(), we create local state in this class. Whenever a local state value changes, the page re-renders.

After calling the GraphHttpClient, we wait for the asynchronous response. If the response is successful. we return the results to the calling component. We are now ready to display the data.

The function above uses the GraphHttpClient class. The
GraphHttpClient class is deprecated and using the MSGraphClient (see this documentation) class is now preferred. The call would look something like this:

export default class HelloWorldWebPart extends BaseClientSideWebPart<IHelloWorldWebPartProps> {
  public render(): void {
    this.context.msGraphClientFactory
      .getClient()
      .then((client: MSGraphClient): void => {
        client
          .api('/users/' + uId )
          .select(['id','businessPhones',
	      'displayName','givenName','jobTitle','mail','mobilePhone',
	      'officeLocation','preferredLanguage','surname',
	      'userPrincipalName','department','companyName'])
          .get((error, response: any, rawResponse?: any) => {
            if (response.ok) {
                return response.json();
            }).then((user:any)=>{
		    this.setState({user:user});
	    });
    });
  }

  // ...do more stuff in your class
}

One of the benefits of Office UI Fabric is that we can use the Persona component to display user information in a way that is consistent with the Office 365 experience.

<Persona   
	imageUrl={this.props.context._pageContext.legacyPageContext.webAbsoluteUrl + 
       '/_layouts/15/userphoto.aspx?size=L&amp;username=' + this.state.user.mail}                             
	primaryText= {this.state.user.displayName}
	secondaryText= {this.state.user.jobTitle}  
	tertiaryText={this.state.user.department} 
	size={PersonaSize.extraLarge}                                                                           
>

Here is what the Persona component looks like when it is rendered:

Persona Component Display

We can further display the remainder of the person details using the React TSX file. The following code block shows the TypeScript and markup for displaying Email, Chat, Mobile and Work Phone fields.

<div className="ms-Grid-col ms-sm12 ms-md6 ms-lg3">
    <Label className={styles.labelStyle}>Email</Label>
    <div>
        <Link href={"mailto:" + this.state.user.mail}>{this.state.user.mail}</Link>
    </div>
    <Label className={styles.labelStyle}>Chat</Label>
    <div>
        <Link href={"SIP:" + this.state.user.userPrincipalName}>{this.state.user.userPrincipalName}</Link>
    </div>
</div>
<div className="ms-Grid-col ms-sm12 ms-md6 ms-lg3">
    <Label className={styles.labelStyle}>Mobile</Label>
    <div>
        <Link href={"tel:" + this.state.user.mobilePhone}>{this.state.user.mobilePhone}</Link>
    </div>
    <Label className={styles.labelStyle}>WorkPhone</Label>
    <div>
        <Link href={"tel:" + this.state.user.businessPhones}>{this.state.user.businessPhones}</Link>
    </div>
</div>

The code above shows how to render the fields in the orange box below:

One final note. In my previous post about connecting to the Microsoft Graph API, I showed how to use the client ID and client secret to connect to the service and get an access token. This was necessary because I was connecting in a console application, which does not have any Office 365 context.

When we do this in a SharePoint Framework web part, there is no need to pass in the client id and client secret. The authentication/authorization is handled via OAuth with an implicit flow. The web part runs with the permissions of the current user.

For some operations, you will need to register your application and set up authentication. See this documentation for more information.

%d bloggers like this:
search previous next tag category expand menu location phone mail time cart zoom edit close