Giter Site home page Giter Site logo

Comments (5)

juliemturner avatar juliemturner commented on September 18, 2024

So, there are a couple of things, one I can see right away and the other I'm not sure because you didn't share enough code. But essentially, you're call in ``

private async _addToCalendar(): Promise<void> {
    const _graph = getGraph(this.props.context);
    const events = await _graph.me.calendar.events();
    console.log(events.length);
    ....

should not be passing this.props.context. The point of the pnpjsConfig.ts file implementation is that you initialize the variable when you're webpart first loads and then when you need an instance of the graphfi interface you can make a call (without context) to return it. Since it looks like you copied this from our sample, I would take a look at the onInit call in the root webpart ts file so you can see what I'm suggesting.

from pnpjs.

pmmarkley avatar pmmarkley commented on September 18, 2024

Thank you for your response, I have removed the this.props.context from the call to getGraph and the behavior is still the same. Below is the code in my CcgTimeRequestVisualizerWebPart.ts. In this file the _getLists function works as expected. This issue only seems related to using graph.

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

import * as strings from 'CcgTimeRequestVisualizerWebPartStrings';
import { ICcgTimeRequestVisualizerProps } from './components/ICcgTimeRequestVisualizerProps';
import { getSP, getGraph } from './pnpjsConfig';
import { LogLevel, Logger } from '@pnp/logging';
import { IList, IListInfo } from '@pnp/sp/lists';
import { SPFI } from '@pnp/sp';
import CcgTimeRequestVisualizer from './components/CcgTimeRequestVisualizer';
import { GraphFI } from '@pnp/graph';

export interface ICcgTimeRequestVisualizerWebPartProps {
  description: string;
  listName: string;
  newFormPageName: string;
  editFormPageName: string;
  privacyEnabled: boolean;
}

export default class CcgTimeRequestVisualizerWebPart extends BaseClientSideWebPart<ICcgTimeRequestVisualizerWebPartProps> {

  private _isDarkTheme: boolean = false;
  private _lists: IPropertyPaneDropdownOption[];
  private _pages: IPropertyPaneDropdownOption[];
  private _listDropdownDisabled: boolean = true;
  private _pageDropdownDisabled: boolean = true;
 
  public render(): void {
    const element =  React.createElement<ICcgTimeRequestVisualizerProps>(
      CcgTimeRequestVisualizer,
      {
        description: this.properties.description,
        isDarkTheme: this._isDarkTheme,
        hasTeamsContext: !!this.context.sdks.microsoftTeams,
        userDisplayName: this.context.pageContext.user.displayName,
        listName: this.properties.listName,
        context: this.context
      }
    );

    ReactDom.render(element, this.domElement);
  }

  protected async onInit(): Promise<void> {
    await super.onInit();

    // Initialize our _sp and _graph objects so we can then use iin other packages without having to pass around the context.
    getSP(this.context);
    getGraph(this.context);
    
  }

  // method to pull all the lists in the current site.
  private _getLists = async (): Promise<void> => {
    this._lists = [];
    try {
      const _sp = getSP();
      const response:IListInfo[] = await _sp.web.lists();
      response.forEach((list: IListInfo) => {
        if (list.BaseTemplate === 100) {
          this._lists.push({
            key: list.Title,
            text: list.Title
          });
        }
      });
    } catch (err) {
      Logger.write(`_getLists - ${JSON.stringify(err)} - `, LogLevel.Error);
    }
  }

  

  protected onThemeChanged(currentTheme: IReadonlyTheme | undefined): void {
    if (!currentTheme) {
      return;
    }

    this._isDarkTheme = !!currentTheme.isInverted;
    const {
      semanticColors
    } = currentTheme;

    if (semanticColors) {
      this.domElement.style.setProperty('--bodyText', semanticColors.bodyText || null);
      this.domElement.style.setProperty('--link', semanticColors.link || null);
      this.domElement.style.setProperty('--linkHovered', semanticColors.linkHovered || null);
    }

  }

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

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


  protected onPropertyPaneConfigurationStart(): void {
    // disable drop down if there are no items
    this._listDropdownDisabled= !this._lists;
    // if the lists dropdown has items, then return
    if(this._lists){
      return;
    }
    this.context.statusRenderer.displayLoadingIndicator(this.domElement,'lists');
    this._getLists().then(() => {
      this._listDropdownDisabled = false;
      this.context.propertyPane.refresh();
      this.context.statusRenderer.clearLoadingIndicator(this.domElement);
    });

  }

  // triggered when there is a change to a property pane item
  // compare the old value with the newly selected value and see if any updates are required.
  protected onPropertyPaneFieldChanged(propertyPath:string, oldValue:any, newValue: any){
    super.onPropertyPaneFieldChanged(propertyPath,oldValue,newValue);
    this.render();
  }
  
  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    return {
      pages: [
        {
          header: {
            description: strings.PropertyPaneDescription
          },
          groups: [
            {
              groupName: strings.BasicGroupName,
              groupFields: [
                PropertyPaneTextField('description', {
                  label: strings.DescriptionFieldLabel
                }),
                PropertyPaneDropdown('listName', {
                  label: strings.ListNameFieldLabel,
                  options: this._lists,
                  disabled: this._listDropdownDisabled
                })
              ]
            }
          ]
        }
      ]
    };
  }
}

And the updated code from my CcgTimeRequestVisualizer.tsx file (removing the this.props.context from the call to getGraph

import * as React from 'react';
import styles from './CcgTimeRequestVisualizer.module.scss';
import type { ICcgTimeRequestVisualizerProps } from './ICcgTimeRequestVisualizerProps';
import { escape } from '@microsoft/sp-lodash-subset';
import { ICcgTimeRequestVisualizerState } from './ICcgTimeRequestVisualizerState';
import { getGraph } from '../pnpjsConfig';
import '@pnp/graph';
import { IUser } from '@pnp/graph/users';

export default class CcgTimeRequestVisualizer extends React.Component<ICcgTimeRequestVisualizerProps, ICcgTimeRequestVisualizerState> {
  
  
  constructor(props: ICcgTimeRequestVisualizerProps) {
    
    super(props);
  }
  
  private async _addToCalendar(): Promise<void> {
    const _graph = getGraph();
    const events = await _graph.me.calendar.events();
    console.log(events.length);
    await _graph.me.calendar.events.add({
      "subject": "Katie Alley - Perk",
      "body": {
        "content": "Katie Alley - Perk"
      },
      "start": {
          "dateTime": "2024-05-10T08:00:00",
          "timeZone": "Eastern Standard Time"
      },
      "end": {
          "dateTime": "2024-05-10T17:00:00",
          "timeZone": "Eastern Standard Time"
      }
    });
  }
  public render(): React.ReactElement<ICcgTimeRequestVisualizerProps> {
    const {
      listName,
      userDisplayName
    } = this.props;

    return (
      <section className={`${styles.ccgTimeRequestVisualizer}`}>
        <div className={styles.welcome}>
          <h2>Well done, {escape(userDisplayName)}!</h2>
          <p>You have selected ${listName}</p>
        </div>
        <button type="button" onClick={ this._addToCalendar.bind(this)}>Add To Calendar</button>
      </section>
    );
  }
}

from pnpjs.

bcameron1231 avatar bcameron1231 commented on September 18, 2024

I'm having trouble reproducing. I don't have any issues with reloading and it's working as expected. Can you provide a bit more context of your environment? What's your browser, are you loading just in SharePoint, Workbench, Teams? Have you tried different browsers?

Looking through some recent issues in the SP-Dev-Docs site, I wonder if it's an issue outside of the library, and a problem on Microsoft's side.

SharePoint/sp-dev-docs#9485

from pnpjs.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.