Don't use PropertyPaneTextField with numeric properties |
Don't use PropertyPaneTextField with numeric properties
CheckId | SPF010803 |
---|---|
TypeName | DontUsePropertyPaneTextFieldWithNumericProperties |
Severity | CriticalWarning |
Type | JavaScriptFile |
When working with numeric properties in SharePoint Framework client-side web parts, you should avoid using the PropertyPaneTextField control to manage values of these properties. The value returned by PropertyPaneTextField is a string, and if not explicitly parsed to a number, it will give incorrect results on runtime.
Consider the following scenario:
SharePoint Framework client-side web part manifest
{
"$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",
"id": "ad1c21c1-a976-4f9e-a896-469e87f53d31",
"alias": "MyRecentDocumentsWebPart",
"componentType": "WebPart",
"version": "0.0.1",
"manifestVersion": 2,
"preconfiguredEntries": [{
"groupId": "ad1c21c1-a976-4f9e-a896-469e87f53d31",
"group": { "default": "Content rollup" },
"title": { "default": "My recent documents" },
"description": { "default": "Shows documents recently viewed or modified by the current user" },
"officeFabricIconFontName": "Recent",
"properties": {
"title": "My recent documents",
"numberOfDocuments": 5
}
}]
}
"$schema": "../../../node_modules/@microsoft/sp-module-interfaces/lib/manifestSchemas/jsonSchemas/clientSideComponentManifestSchema.json",
"id": "ad1c21c1-a976-4f9e-a896-469e87f53d31",
"alias": "MyRecentDocumentsWebPart",
"componentType": "WebPart",
"version": "0.0.1",
"manifestVersion": 2,
"preconfiguredEntries": [{
"groupId": "ad1c21c1-a976-4f9e-a896-469e87f53d31",
"group": { "default": "Content rollup" },
"title": { "default": "My recent documents" },
"description": { "default": "Shows documents recently viewed or modified by the current user" },
"officeFabricIconFontName": "Recent",
"properties": {
"title": "My recent documents",
"numberOfDocuments": 5
}
}]
}
Web part properties interface
export interface IMyRecentDocumentsWebPartProps {
numberOfDocuments: number;
title: string;
}
numberOfDocuments: number;
title: string;
}
Web part code
// ...
export default class MyRecentDocumentsWebPart extends BaseClientSideWebPart<IMyRecentDocumentsWebPartProps> {
public render(): void {
this.domElement.innerHTML = `
<div class="${styles.helloWorld}">
<div class="${styles.container}">
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
<span class="ms-font-xl ms-fontColor-white">Welcome to SharePoint!
<p class="ms-font-l ms-fontColor-white">Customize SharePoint experiences using Web Parts.
<p class="ms-font-l ms-fontColor-white">${escape(this.properties.title)}
<span class="${styles.label}">Learn more
export default class MyRecentDocumentsWebPart extends BaseClientSideWebPart<IMyRecentDocumentsWebPartProps> {
public render(): void {
this.domElement.innerHTML = `
<div class="${styles.helloWorld}">
<div class="${styles.container}">
<div class="ms-Grid-row ms-bgColor-themeDark ms-fontColor-white ${styles.row}">
<div class="ms-Grid-col ms-u-lg10 ms-u-xl8 ms-u-xlPush2 ms-u-lgPush1">
<span class="ms-font-xl ms-fontColor-white">Welcome to SharePoint!
<p class="ms-font-l ms-fontColor-white">Customize SharePoint experiences using Web Parts.
<p class="ms-font-l ms-fontColor-white">${escape(this.properties.title)}
<span class="${styles.label}">Learn more
const numberOfDocumentsToLoad: number = this.properties.numberOfDocuments + 5;
console.log(numberOfDocumentsToLoad);
}
// ...
}
On the first run, the web part uses the default value from the web part manifest, which is number 5 and which results in a correct sum with the result of 10. Once the user however changes the value of the property through the property pane, the value changes to a string and the above code results in a string concatenation rather than a sum returning '55' instead of '10'. Becase the numberOfDocuments property is defined as number, the error isn't caught by TypeScript during transpilation, but it still occurs on runtime.
To solve this issue, you would either use a different control, such as PropertyPaneSlider, to manage the value of the property or change the type of the property to string and parse the provided value as number before using it:
const numberOfDocuments: number = parseInt(escape(this.properties.numberOfDocuments));
let numberOfDocumentsToLoad: number = 5;
if (!isNaN(numberOfDocuments)) {
numberOfDocumentsToLoad += numberOfDocuments;
}
let numberOfDocumentsToLoad: number = 5;
if (!isNaN(numberOfDocuments)) {
numberOfDocumentsToLoad += numberOfDocuments;
}