Chapter 3 - GraphAPI Calendar Events Demo

Create a folder CreateAPIEventsDemo and create react webpart

install types for graph api as below. which adds dev dependencies to our JSON files.

"npm install @microsoft/microsoft-graph-types --save-dev"

now go to components-.ts file 

We are adding context 

context:WebPartContext
-------------------------------------------
Created a new file in components folder ICalendarEventsState.ts
import * as MicrosoftGraph from '@microsoft/microsoft-graph-types';

export interface ICalendarEventsDemoState{
    events:MicrosoftGraph.Event[];
}

We have created ICalendarEventsDemoState interface with events as property with array of events from MicrosoftGraph.

for our convenience we import graphapi types import * as MicrosoftGraph from '@microsoft/microsoft-graph-types';

----------------
In Main.ts file
public render(): void {
    const elementReact.ReactElement<ICalendarEventsDemoProps> = React.createElement(
      CalendarEventsDemo,
      {
        description: this.properties.description,
        context: this.context
      }
    );

    ReactDom.render(elementthis.domElement);
  }
I have add context property.
-------------------------
Now in .tsx file, 
Import
import { MSGraphClient } from '@microsoft/sp-http';
import * as MicrosoftGraph from '@microsoft/microsoft-graph-types';

We need to add our State interface to our .tsx file.
and add constructore method

constructor(props:ICalendarEventsDemoProps) {
    super(props);
    this.state = {
      events = []
    }
  }

Then creating a componentDidMount for Rest API to get values of events.
public componentDidMount():void {
    this.props.context.MSGraphClient.getClient().then((client:MSGraphClient):void => {
      client.api('me/calendar/events')
      .version("v1.0")
      .select("*")
      .get((error:anyeventsResponserawResponse?:any)=>{
        if(error){
          console.error("Message is: "+error);
        }
        const calendarEventsMicrosoftGraph.Event[] = eventsResponse.value;
        this.setState({events:calendarEvents})
      })
    })
  }

Now go to render method
 public render(): React.ReactElement<ICalendarEventsDemoProps> {
    return (
      <div>
        <ul>
          {
            this.state.events.map((itemkey)=>{
              <li key={item.id}>
                {item.subject},
                {item.organizer.emailAddress.name},
                {item.start.dateTime.substr(0,10)},{item.start.dateTime.substr(12,5)},
                {item.end.dateTime.substr(0,10)},{item.end.dateTime.substr(12,5)}
              </li>
            })
          }
        </ul>

        <style>
          {`
          table{
            border:1px solid black;
            backgroud:aqua;
          }
          `}
        </style>
        
        <table>
          <tr>
            <td>Subject</td>
            <td>Organizer name</td>
            <td>Start Date</td>
            <td>Start Time</td>
            <td>End Date</td>
            <td>End Time</td>
          </tr>
          {
            this.state.events.map((item,key)=>{
              <tr>
                <td>{item.subject}</td>
                <td>{item.organizer.emailAddress.name}</td>
                <td>{item.start.dateTime.substr(0,10)}</td>
                <td>{item.start.dateTime.substr(12,5)}</td>
                <td>{item.end.dateTime.substr(0,10)}</td>
                <td>{item.end.dateTime.substr(12,5)}</td>
              </tr>
            })
          }
        </table>
      </div>
    );
  }
------------------------------------------------
Before we build and deploy, we need to assign permissions to graph api to run it.
In config folder- go to package-solution.json

Note in graph explore we did consent permission in graph explore purpose only. 

Add webapirequests with Calendars.Read to make permissions to read all the events from calendar through our Webpart.

{
  "$schema""https://developer.microsoft.com/json-schemas/spfx-build/package-solution.schema.json",
  "solution": {
    "name""graph-api-events-demo-client-side-solution",
    "id""867b0c19-4114-4149-ab46-5326e711a47c",
    "version""1.0.0.0",
    "includeClientSideAssets"true,
    "isDomainIsolated"false,
    "webApiPermissionRequests": [
      {
        "resource""Microsoft Graph",
        "scope":"Calendars.Read"
      }
    ],
    "developer": {
      "name""",
      "websiteUrl""",
      "privacyUrl""",
      "termsOfUseUrl""",
      "mpnId"""
    }
  },
  "paths": {
    "zippedPackage""solution/graph-api-events-demo.sppkg"
  }
}

-----------------------------------------------------

.tsx code:

import * as React from 'react';
import styles from './CalendarEventsDemo.module.scss';
import { ICalendarEventsDemoProps } from './ICalendarEventsDemoProps';
import { escape } from '@microsoft/sp-lodash-subset';

import { MSGraphClient } from '@microsoft/sp-http';
import * as MicrosoftGraph from '@microsoft/microsoft-graph-types';
import { ICalendarEventsDemoState } from './ICalendarEventsState';

export default class CalendarEventsDemo extends React.Component<ICalendarEventsDemoProps,ICalendarEventsDemoState, {}> {

  constructor(props:ICalendarEventsDemoProps) {
    super(props);
    this.state = {
      events : []
    }
  }
  public componentDidMount():void {
    this.props.context.msGraphClientFactory.getClient().then((client:MSGraphClient):void => {
      client.api('me/calendar/events')
      .version("v1.0")
      .select("*")
      .get((error:anyeventsResponserawResponse?:any)=>{
        if(error){
          console.error("Message is: "+error);
        }
        const calendarEventsMicrosoftGraph.Event[] = eventsResponse.value;
        this.setState({events:calendarEvents})
      })
    })
  }

  public render(): React.ReactElement<ICalendarEventsDemoProps> {
    return (
      <div>
        <ul>
          {
            this.state.events.map((itemkey)=>{
              <li key={item.id}>
                {item.subject},
                {item.organizer.emailAddress.name},
                {item.start.dateTime.substr(0,10)},{item.start.dateTime.substr(12,5)},
                {item.end.dateTime.substr(0,10)},{item.end.dateTime.substr(12,5)}
              </li>
            })
          }
        </ul>

        <style>
          {`
          table{
            border:1px solid black;
            backgroud:aqua;
          }
          `}
        </style>
        
        <table>
          <tr>
            <td>Subject</td>
            <td>Organizer name</td>
            <td>Start Date</td>
            <td>Start Time</td>
            <td>End Date</td>
            <td>End Time</td>
          </tr>
          {
            this.state.events.map((item,key)=>{
              <tr>
                <td>{item.subject}</td>
                <td>{item.organizer.emailAddress.name}</td>
                <td>{item.start.dateTime.substr(0,10)}</td>
                <td>{item.start.dateTime.substr(12,5)}</td>
                <td>{item.end.dateTime.substr(0,10)}</td>
                <td>{item.end.dateTime.substr(12,5)}</td>
              </tr>
            })
          }
        </table>
      </div>
    );
  }
}
----------------------------------
Main ts file

import * as React from 'react';
import * as ReactDom from 'react-dom';
import { Version } from '@microsoft/sp-core-library';
import {
  IPropertyPaneConfiguration,
  PropertyPaneTextField
from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';

import * as strings from 'CalendarEventsDemoWebPartStrings';
import CalendarEventsDemo from './components/CalendarEventsDemo';
import { ICalendarEventsDemoProps } from './components/ICalendarEventsDemoProps';

export interface ICalendarEventsDemoWebPartProps {
  descriptionstring;
}

export default class CalendarEventsDemoWebPart extends BaseClientSideWebPart<ICalendarEventsDemoWebPartProps> {

  public render(): void {
    const elementReact.ReactElement<ICalendarEventsDemoProps> = React.createElement(
      CalendarEventsDemo,
      {
        description: this.properties.description,
        context: this.context
      }
    );

    ReactDom.render(elementthis.domElement);
  }

  protected onDispose(): void {
    ReactDom.unmountComponentAtNode(this.domElement);
  }

  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
                })
              ]
            }
          ]
        }
      ]
    };
  }
}
---------------------------------

components folder interface props .ts

import { WebPartContext } from "@microsoft/sp-webpart-base";

export interface ICalendarEventsDemoProps {
  descriptionstring;
  context:WebPartContext
}
------------------------------

state file .ts

import * as MicrosoftGraph from '@microsoft/microsoft-graph-types';

export interface ICalendarEventsDemoState{
    events:MicrosoftGraph.Event[];
}
----------------------------------------

Comments