SPFx IPropertyPaneDropdownOption[] get Unique Options (Duplicates) Cascade

January 21, 2024 By Joao LIVIO

When designing the property pane for your SharePoint client-side web parts, you may have one web part property that displays its options based on the value selected in another property. This scenario typically occurs when implementing cascading dropdown controls.

I’m assuming in this Article/Fix you are getting all lists excluding the hidden ones. Let’s Start from the beginning, you have an article from microsoft explaining how to cascade properties here you have also a sample in the PnP WebPat Samples

No let’s assume you want to remove duplicates for items after choosing a list. From the options you must resolve(options), this can be a little bit tricky, but you can take advantage of the uniqBy importing '@microsoft/sp-lodash-subset', it’s in the Dev Chain 🙂

uniqBy Lodash _.uniqBy method is similar to uniq _.uniq except that it accepts iteratee which is invoked for each element in an array to generate the criterion by which uniqueness is computed. The order of result values is determined by the order they occur in the array.

Let’s see an example

import { uniqBy } from '@microsoft/sp-lodash-subset';

//* Omitted for abbreviation */

private lists: IPropertyPaneDropdownOption[];
private items: IPropertyPaneDropdownOption[];
private listsDropdownDisabled: boolean = true;
private itemsDropdownDisabled: boolean = true;
private loadingIndicator: boolean = true;

//* Omitted for abbreviation */

protected async onPropertyPaneConfigurationStart(): Promise<void> {
    //* Omitted for abbreviation */
    
    // load the items from SharePoint
    const itemOptions: IPropertyPaneDropdownOption[] = await this.loadItems();
    this.items = itemOptions;
    this.itemsDropdownDisabled = !this.properties.listName;
    this.context.propertyPane.refresh();

    //* Omitted for abbreviation */
}
protected async onPropertyPaneFieldChanged(propertyPath: string, oldValue: any, newValue: any): Promise<void> {
    //* Omitted for abbreviation */
}

//* await this.loadItems()*/

private async loadItems(): Promise<IPropertyPaneDropdownOption[]> {
    if (!this.properties.listName) {
      // return empty options since no list has been selected
      return [];
    }
    const sp = spfi().using(SPFx(this.context));
    // This is where you'd replace the mock data with the actual data from SharePoint
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    return await new Promise<IPropertyPaneDropdownOption[]>((resolve: (options: IPropertyPaneDropdownOption[]) => void, reject: (error: any) => void) => {
      // timeout to simulate async call
      // YOUR_COLUMN have .filter('YOUR_COLUMN gt 0') because I want only to catch all containing values of a choice field 
      sp.web.lists.getByTitle(this.properties.listName).items.select('Id', 'YOUR_COLUMN').filter('YOUR_COLUMN gt 0').orderBy('YOUR_COLUMN')().then((items) => {
        const options: IPropertyPaneDropdownOption[] = items.map((item) => {
          return {
            key: item.YOUR_COLUMN,
            text: item.YOUR_COLUMN
          };
        });

        //* MAGIC START HERE */
        //* import { uniqBy } from '@microsoft/sp-lodash-subset'; */
        let uniq = uniqBy(options, function (o) {
          return o.text;
        });
        //* Instead of resolve options you should resolve uniq it's done */
        resolve(uniq);
      });
    });
  }

Lodash _.uniqBy() Method

_.uniqBy([array], [iteratee = _.identity])

Sintax

Parameters:

  • [arrays]: This parameter holds the arrays to inspect.
  • [iteratee=_.identity]: This parameter holds the iteratee invoked per element.

Return Value:

This method is used to return the new duplicate free array.

Leave a comment if in did help you