Skip to content

PropertyFieldListPicker control failing with Cannot read properties of undefined (reading 'id') #616

@JesperGSimonsen

Description

@JesperGSimonsen

Category

  • Enhancement
  • Bug
  • Question

Version

Please specify what version of the library you are using: [ "@pnp/spfx-property-controls": "3.17.0", ]

Expected / Desired Behavior / Question

To create a new solution, e.g like described in https://nanddeepnachanblogs.com/posts/2019-05-14-pnp-property-pane-controls-for-spfx/ and get the list picker function to work.

Observed Behavior

Following the steps from the above url or the ones from https://pnp.github.io/sp-dev-fx-property-controls/controls/PropertyFieldListPicker/#implementation, VS Code gives two errors: In the inserted PropertyFieldListPicker in the getPropertyPaneConfiguration, context gives this error:
Type 'WebPartContext' is not assignable to type 'BaseComponentContext'.
Types have separate declarations of a private property '_serviceScope'.ts(2322)
IPropertyFieldListPicker.d.ts(39, 5): The expected type comes from property 'context' which is declared here on type 'IPropertyFieldListPickerProps'

And onGetErrorMessage give this error:
Type 'null' is not assignable to type '((value: string) => string | Promise) | undefined'.ts(2322)
IPropertyFieldListPicker.d.ts(107, 5): The expected type comes from property 'onGetErrorMessage' which is declared here on type 'IPropertyFieldListPickerProps'

Changing context to context: this.context as any;
and changing onGetErrorMessage to onGetErrorMessage: undefined:
removes the erros and makes it possible to run a gulp serve

Trying to add the webpart gives an error:
Something went wrong
If the problem persists, contact the site administrator and give them the information in Technical Details.
TECHNICAL DETAILS
ERROR:
Cannot read properties of undefined (reading 'id')

CALL STACK:
TypeError: Cannot read properties of undefined (reading 'id')
at https://res-1.cdn.office.net/files/sp-client/sp-webpart-workbench-assembly_en-us_75d50594e595fa477e6cc5378ce44605.js:196:10988
at new Promise ()
at e.loadComponent (https://res-1.cdn.office.net/files/sp-client/sp-webpart-workbench-assembly_en-us_75d50594e595fa477e6cc5378ce44605.js:196:10956)
at https://res-1.cdn.office.net/files/sp-client/sp-webpart-workbench-assembly_en-us_75d50594e595fa477e6cc5378ce44605.js:196:13164
at async Promise.all (index 1)

Steps to Reproduce

Follow the steps to build a list picker as described in above urls, correct the context and the OnGetErrorMessage, run a gulp serve and add the web part.

Full code of ListPickerWebPart.ts:
import { Version } from '@microsoft/sp-core-library';
import {
type IPropertyPaneConfiguration,
PropertyPaneTextField
} from '@microsoft/sp-property-pane';
import { BaseClientSideWebPart } from '@microsoft/sp-webpart-base';
import type { IReadonlyTheme } from '@microsoft/sp-component-base';
import { escape } from '@microsoft/sp-lodash-subset';
import { PropertyFieldListPicker, PropertyFieldListPickerOrderBy } from '@pnp/spfx-property-controls/lib/PropertyFieldListPicker';
import styles from './ListPickerWebPart.module.scss';
import * as strings from 'ListPickerWebPartStrings';

export interface IListPickerWebPartProps {
description: string;
lists: string | string[]; // Stores the list ID(s)
}

export default class ListPickerWebPart extends BaseClientSideWebPart {

private _isDarkTheme: boolean = false;
private _environmentMessage: string = '';

public render(): void {
this.domElement.innerHTML = <section class="${styles.listPicker} ${!!this.context.sdks.microsoftTeams ? styles.teams : ''}"> <div class="${styles.welcome}"> <img alt="" src="${this._isDarkTheme ? require('./assets/welcome-dark.png') : require('./assets/welcome-light.png')}" class="${styles.welcomeImage}" /> <h2>Well done, ${escape(this.context.pageContext.user.displayName)}!</h2> <div>${this._environmentMessage}</div> <div>Web part property value: <strong>${escape(this.properties.description)}</strong></div> </div> <div> <h3>Welcome to SharePoint Framework!</h3> <p> The SharePoint Framework (SPFx) is a extensibility model for Microsoft Viva, Microsoft Teams and SharePoint. It's the easiest way to extend Microsoft 365 with automatic Single Sign On, automatic hosting and industry standard tooling. </p> <h4>Learn more about SPFx development:</h4> <ul class="${styles.links}"> <li><a href="https://aka.ms/spfx" target="_blank">SharePoint Framework Overview</a></li> <li><a href="https://aka.ms/spfx-yeoman-graph" target="_blank">Use Microsoft Graph in your solution</a></li> <li><a href="https://aka.ms/spfx-yeoman-teams" target="_blank">Build for Microsoft Teams using SharePoint Framework</a></li> <li><a href="https://aka.ms/spfx-yeoman-viva" target="_blank">Build for Microsoft Viva Connections using SharePoint Framework</a></li> <li><a href="https://aka.ms/spfx-yeoman-store" target="_blank">Publish SharePoint Framework applications to the marketplace</a></li> <li><a href="https://aka.ms/spfx-yeoman-api" target="_blank">SharePoint Framework API reference</a></li> <li><a href="https://aka.ms/m365pnp" target="_blank">Microsoft 365 Developer Community</a></li> </ul> </div> </section>;
}

protected onInit(): Promise {
return this._getEnvironmentMessage().then(message => {
this._environmentMessage = message;
});
}

private _getEnvironmentMessage(): Promise {
if (!!this.context.sdks.microsoftTeams) { // running in Teams, office.com or Outlook
return this.context.sdks.microsoftTeams.teamsJs.app.getContext()
.then(context => {
let environmentMessage: string = '';
switch (context.app.host.name) {
case 'Office': // running in Office
environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentOffice : strings.AppOfficeEnvironment;
break;
case 'Outlook': // running in Outlook
environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentOutlook : strings.AppOutlookEnvironment;
break;
case 'Teams': // running in Teams
case 'TeamsModern':
environmentMessage = this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentTeams : strings.AppTeamsTabEnvironment;
break;
default:
environmentMessage = strings.UnknownEnvironment;
}

      return environmentMessage;
    });
}

return Promise.resolve(this.context.isServedFromLocalhost ? strings.AppLocalEnvironmentSharePoint : strings.AppSharePointEnvironment);

}

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 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
}),
PropertyFieldListPicker('lists', {
label: 'Select a list',
selectedList: this.properties.lists,
includeHidden: false,
orderBy: PropertyFieldListPickerOrderBy.Title,
disabled: false,
onPropertyChange: this.onPropertyPaneFieldChanged.bind(this),
properties: this.properties,
context: this.context as any,
onGetErrorMessage: undefined,
deferredValidationTime: 0,
key: 'listPickerFieldId'
})
]
}
]
}
]
};
}
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions