Display Other User Events in SPFx Webpart

In this article, I have explained how to retrieve the other user calendar events in SPFx webpart with the help of Microsoft Graph API.

Before continue this article Please use the below link to know about Azure App Registration & how to fetch access token via OAuth

After register your application in azure portal click on API permission for the application you created then choose Microsoft Graph API -> choose Application Permission then add the permission mentioned below and grant admin consent for the tenant. Add the Redirect URL of the web application to authenticate. For testing purpose i have included my site workbench URL

  • Calendar.Read
  • User.Read.All

Now am going to create a SPFx Project with “No Javascript Framework” template and Install the below NPM Packages.

npm install axios  // For sending HTTP request
npm install lodash //For array collections
npm install moment // For formatting dates

Open up the folder src -> webpart -> FetchEventWebpart.ts file then create a method “RetriveAccessToken()” to sending request to fetch access token

private RetriveAccessToken() {
    axios({
      method: 'post',
      url: 'https://login.microsoftonline.com/sharepointtechie.onmicrosoft.com/oauth2/v2.0/token',
      data: JSON.stringify({
        grant_type: "client_credentials",
        client_id: "8baf0301-27df-44b1-b4fe-7911b9a918de", //Provide your app id    
        client_secret: "tZ76oVPN039WlWPoAp+1aICq66vs7oUtE4lhDQYwxGY=", //Provide your secret    
        scope: "https://graph.microsoft.com/.default"
      }),
      headers: {
        'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    }).then((response) => {
      let token: string = response.data.access_token;
      console.log("token", token)     
    }).catch((error) => {
       console.log("error",error)
    })
  }

Once you retrieved the access token create another method to send Graph API request to get calendar events

 public FetchAllEvents(token: string){    //Pass the token parameter 
     axios({
       method: 'get',
       url: graphConfig.graphEndPoint,
       headers: {
         'authorization': 'Bearer ' + token,   //set the parameter
         'content-type': 'application/json'
       },
     }).then((items) => {
         let events: any = items.data.value;
          console.log("items", events)  //Print the events in console
     }).catch((error) => {
          console.log("error", error)
     })
  }

Full Code:

import { Version } from '@microsoft/sp-core-library';
import {
  IPropertyPaneConfiguration,
  PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import axios from 'axios';
import * as moment from 'moment';
import { SPComponentLoader } from '@microsoft/sp-loader';
import * as strings from 'FetchEventsWebPartStrings';
import * as _ from 'lodash';

export interface IFetchEventsWebPartProps {
  description: string;
}

//Load the sematic UI
SPComponentLoader.loadCss('https://cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.4.1/semantic.min.css');

//Graph endpoint setup
const graphConfig = {
  graphEndPoint: "https://graph.microsoft.com/v1.0/users/vijayalakshmi@sharepointtechie.onmicrosoft.com/calendar/events"
};


export default class FetchEventsWebPart extends BaseClientSideWebPart<IFetchEventsWebPartProps> {

  private RetriveAccessToken() {
    axios({
      method: 'post',
      url: 'https://howling-crypt-47129.herokuapp.com/https://login.microsoftonline.com/sharepointtechie.onmicrosoft.com/oauth2/v2.0/token',
      data: qs.stringify({
        grant_type: "client_credentials",
        client_id: "8baf0301-27df-44b1-b4fe-7911b9a918de", //Provide your app id
        client_secret: "tZ76oVPN039WlWPoAp+1aICq66vs7oUtE4lhDQYwxGY=", //Provide your secret
        scope: "https://graph.microsoft.com/.default"
      }),
      headers: {
        'content-type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    }).then((response) => {
      let token: string = response.data.access_token;
      if (token != undefined) {
        this.FetchAllEvents(token)
      }
    }).catch((error) => {
      console.log("error", error)
    })
  }

  public FetchAllEvents(token: string) {
    axios({
      method: 'get',
      url: graphConfig.graphEndPoint,
      headers: {
        'authorization': 'Bearer ' + token,
        'content-type': 'application/json'
      },
    }).then((items) => {
      let events: any = items.data.value;
      let html: string = "";
      let attandeesInfo = [];

      events.forEach(value => {
        let bodyContent = (value.bodyPreview != "") ? '<div class="ui label">Description: </div> <br> ' + value.body.content + ' ' :
          '<div class="ui label">Description: </div><br>No message to preview'

//Iterate over attendees
        value.attendees.map((users, index) => {
          attandeesInfo.push(users.emailAddress.name)
        })

        html += `
        <div class="card">
        <div class="content">
          <div class="header">
          <div class="ui label">Organizer: </div>  ${value.organizer.emailAddress.name}
          </div> <br>
          <div class="meta">
          <div class="ui label">Attendees: </div>  ${_.uniq(attandeesInfo).toString()}
          </div><br>
          <div class="meta">
          <div class="ui label">Subject: </div> ${value.subject}
          </div><br>
          <div class="description">
          ${bodyContent}
          </div>
        </div>
        <div class="extra content">
          <div class="ui two buttons">
            <div class="ui basic green button">${moment(value.start.dateTime).format('DD/MM/YYYY')}</div>
            <div class="ui basic red button">${moment(value.end.dateTime).format('DD/MM/YYYY')}</div>
          </div>
        </div>
      </div>
        `
      })

      document.getElementsByClassName('ui cards')[0].innerHTML = html

    }).catch((error) => {
      console.log("error", error)
    })
  }

  public render(): void {
    this.domElement.innerHTML = `
    <div class="ui cards"></div>`;

    //Trigger the function onload
    this.RetriveAccessToken()
  }

  protected get dataVersion(): Version {
    return Version.parse('1.0');
  }

  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: {
            description: strings.PropertyPaneDescription
          },
          groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPaneTextField('description', {
                  label: strings.DescriptionFieldLabel
                })
              ]
            }
          ]
        }
      ]
    };
  }
}

Let me deploy the package into my tenant app catalog site and add it into the modern/communication site

Now finally it look like below

Keep Sharing!…

Author Profile

Vinodh
Vinodh is a Microsoft MVP for SharePoint (Office Apps and Services) having 5+ years of experience in Microsoft Technologies.

His interest and expertise includes SharePoint Online Development, PowerApps Development, Flows for SharePoint and PowerApps. Single Page Apps/Add ins for SharePoint using React, Angular. SharePoint Farm Management, 2, 3 and upto 6 tier SharePoint Farm Installation and Configuration.

Awards :
Microsoft Most Valuable Professional for SharePoint and Office 365 awarded for the year 2016, 2017 and 2018.
C# Corner Most Valuable Professional for SharePoint and Office 365 awarded for the year 2016, 2017 and 2018.
Technology Expertise :
SharePoint Online, SharePoint 2013, SharePoint 2016 and SharePoint 2019 Preview.
Intranets both Modern and Classic, SharePoint Frameworks Customisation, SharePoint Add-ins, SharePoint single page apps.
Angular 5 with Bootstrap single page apps.
Typescript, JQuery and Javascript.
Micrsoft Flow and Powerapps.
Utilised :
Microsoft Graph API, SharePoint REST, SharePoint PnP JS.
Out of Box :
Consume Content search web parts for internet publishing sites using custom display templates.
Having knowledge on SharePoint workflows and SharePoint Designer workflows.
List customisation using JS Link, JSON Formatting.
Having knowledge in Active directory management services.
Create and configure service applications in SharePoint (MMS, UPSA, SSA).
Configure Outgoing email settings using SMTP Services.

Add a Comment

Your email address will not be published. Required fields are marked *