Webpart list property using PNPJS

%3CLINGO-SUB%20id%3D%22lingo-sub-875669%22%20slang%3D%22en-US%22%3EWebpart%20list%20property%20using%20PNPJS%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-875669%22%20slang%3D%22en-US%22%3E%3CP%3EI%20am%20writing%20a%20simple%20web%20part.%20It%20takes%20a%20property%20of%20%22List%22.%20The%20user%20will%20pick%20the%20list%20from%20a%20dropdown.%20I%20am%20using%20the%20tutorial%20found%20here%3A%3C%2FP%3E%3CP%3E%3CA%20href%3D%22https%3A%2F%2Fwww.sharepointnutsandbolts.com%2F2016%2F09%2Fsharepoint-framework-spfx-web-part-properties-dynamic-dropdown.html%22%20target%3D%22_blank%22%20rel%3D%22noopener%20nofollow%20noreferrer%22%3Ehttps%3A%2F%2Fwww.sharepointnutsandbolts.com%2F2016%2F09%2Fsharepoint-framework-spfx-web-part-properties-dynamic-dropdown.html%3C%2FA%3E%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EI%20have%20the%20following%20function%20that%20uses%20PNPJS%20to%20return%20an%20array%20of%20the%20lists%20on%20the%20site.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-javascript%22%3E%3CCODE%3E%20%20protected%20fetchLists()%3A%20Array%3CIPROPERTYPANEDROPDOWNOPTION%3E%20%7B%0A%20%20%20%20let%20options%3A%20Array%3CIPROPERTYPANEDROPDOWNOPTION%3E%20%3D%20new%20Array%3CIPROPERTYPANEDROPDOWNOPTION%3E()%3B%0A%20%20%20%20sp.web.lists.select('ID'%2C%20'Title'%2C%20'DefaultViewUrl').get().then(function(data)%20%7B%0A%20%20%20%20%20%20for%20(let%20i%20%3D%200%3B%20i%20%26lt%3B%20data.length%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20if%20(data%5Bi%5D.DefaultViewUrl.includes('%2FLists%2F'))%20%7B%0A%20%20%20%20%20%20%20%20%20%20options.push(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20key%3A%20data%5Bi%5D.Title%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20data%5Bi%5D.Title%2C%0A%20%20%20%20%20%20%20%20%20%20%7D)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20console.log(options)%3B%0A%20%20%20%20%7D)%3B%0A%20%20%20%20return%20options%3B%0A%20%20%7D%3C%2FIPROPERTYPANEDROPDOWNOPTION%3E%3C%2FIPROPERTYPANEDROPDOWNOPTION%3E%3C%2FIPROPERTYPANEDROPDOWNOPTION%3E%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CDIV%3E%3CDIV%3EThe%20above%20function%20is%20called%20in%20the%20getPropertyPaneConfiguration%20with%20the%20line%3A%26nbsp%3B%3C%2FDIV%3E%3CDIV%3Elet%20lists%3A%20Array%3CIPROPERTYPANEDROPDOWNOPTION%3E%20%3D%20this.fetchLists()%3B%3C%2FIPROPERTYPANEDROPDOWNOPTION%3E%3C%2FDIV%3E%3C%2FDIV%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-javascript%22%3E%3CCODE%3E%20%20protected%20getPropertyPaneConfiguration()%3A%20IPropertyPaneConfiguration%20%7B%0A%20%20%20%20let%20lists%3A%20Array%3CIPROPERTYPANEDROPDOWNOPTION%3E%20%3D%20this.fetchLists()%3B%0A%20%20%20%20return%20%7B%0A%20%20%20%20%20%20pages%3A%20%5B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20header%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20description%3A%20this.description%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20groups%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20groupName%3A%20'Properties'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20groupFields%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20PropertyPaneDropdown('list'%2C%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label%3A%20'List'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20options%3A%20lists%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D)%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20PropertyPaneTextField('field'%2C%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label%3A%20'Field'%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%5D%0A%20%20%20%20%7D%20%20%0A%20%20%7D%3C%2FIPROPERTYPANEDROPDOWNOPTION%3E%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CP%3EThe%20problem%20is%20the%20sp.web.lists...%20call%20is%20seen%20by%20the%20editor%20as%20not%20ways%20returning%20a%20value.%20I%20have%20tried%20to%20use%20the%20.then(function()%20%7B%7D)%20to%20return%20the%20array%20but%20the%20IDE%20still%20says%20not%20all%20paths%20return%20a%20value.%20How%20can%20I%20satisfy%20the%20IDE%20and%20still%20always%20get%20a%20return%20array%20(even%20if%20it%20is%20empty)%3F%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-LABS%20id%3D%22lingo-labs-875669%22%20slang%3D%22en-US%22%3E%3CLINGO-LABEL%3Ecallback%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EgetPropertyPaneConfiguration%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3EIPropertyPaneDropdownOption%3C%2FLINGO-LABEL%3E%3CLINGO-LABEL%3Epnpjs%3C%2FLINGO-LABEL%3E%3C%2FLINGO-LABS%3E%3CLINGO-SUB%20id%3D%22lingo-sub-875700%22%20slang%3D%22en-US%22%3ERe%3A%20Webpart%20list%20property%20using%20PNPJS%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-875700%22%20slang%3D%22en-US%22%3E%3CP%3ESo%20I%20made%20the%20following%20changes.%20I%20added%20the%20catch%20method%20and%20put%20another%20return%20in%20there%20but%20the%20IDE%20still%20doesn't%20think%20that%20my%20code%20always%20returns%20as%20a%20value.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-javascript%22%3E%3CCODE%3E%20%20protected%20fetchLists()%3A%20Array%3CIPROPERTYPANEDROPDOWNOPTION%3E%20%7B%0A%20%20%20%20let%20options%3A%20Array%3CIPROPERTYPANEDROPDOWNOPTION%3E%20%3D%20new%20Array%3CIPROPERTYPANEDROPDOWNOPTION%3E()%3B%0A%20%20%20%20sp.web.lists.select('ID'%2C%20'Title'%2C%20'DefaultViewUrl').orderBy('Title').get().then(function(data)%20%7B%0A%20%20%20%20%20%20for%20(let%20i%20%3D%200%3B%20i%20%26lt%3B%20data.length%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20if%20((data%5Bi%5D.DefaultViewUrl.includes('%2FLists%2F'))%20%26amp%3B%26amp%3B%20%0A%20%20%20%20%20%20%20%20(%0A%20%20%20%20%20%20%20%20%20%20(data%5Bi%5D.Title%20!%3D%20'SharePointHomeCacheList')%20%7C%7C%20%0A%20%20%20%20%20%20%20%20%20%20(data%5Bi%5D.Title%20!%3D%20'TaxonomyHiddenList')%0A%20%20%20%20%20%20%20%20))%20%7B%0A%20%20%20%20%20%20%20%20%20%20options.push(%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20key%3A%20data%5Bi%5D.Title%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20text%3A%20data%5Bi%5D.Title%2C%0A%20%20%20%20%20%20%20%20%20%20%7D)%3B%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20return%20options%3B%0A%20%20%20%20%7D).catch(function(e)%20%7B%0A%20%20%20%20%20%20return%20options%3B%0A%20%20%20%20%7D)%3B%0A%20%20%7D%3C%2FIPROPERTYPANEDROPDOWNOPTION%3E%3C%2FIPROPERTYPANEDROPDOWNOPTION%3E%3C%2FIPROPERTYPANEDROPDOWNOPTION%3E%3C%2FCODE%3E%3C%2FPRE%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-875702%22%20slang%3D%22en-US%22%3ERe%3A%20Webpart%20list%20property%20using%20PNPJS%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-875702%22%20slang%3D%22en-US%22%3EI%20also%20tried%20to%20change%20the%20return%20object%20of%20the%20function%20to%20%22any%22%2C%20and%20that%20will%20compile%20but%20the%20list%20doesn't%20come%20out%20in%20the%20right%20format%20for%20the%20getPropertyPaneConfiguration%20method.%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-877489%22%20slang%3D%22en-US%22%3ERe%3A%20Webpart%20list%20property%20using%20PNPJS%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-877489%22%20slang%3D%22en-US%22%3EI%20have%20concluded%20that%20my%20problem%20is%20asynchronous%20code%20execution.%20I%20have%20two%20functions%20that%20return%20a%20value.%20function%20A%20calls%20function%20B%20and%20needs%20to%20wait%20for%20the%20reply%20before%20it%20continues.%20This%20may%20be%20more%20complicated%20because%20function%20B%20calls%20another%20function%20with%20a%20callback.%20That%20I%20can't%20figure%20out%20is%20how%20to%20make%20function%20B%20a%20callback%20when%20I%20don't%20control%20when%20function%20A%20gets%20called.%3CBR%20%2F%3E%3CBR%20%2F%3E%3C%2FLINGO-BODY%3E%3CLINGO-SUB%20id%3D%22lingo-sub-877777%22%20slang%3D%22en-US%22%3ERe%3A%20Webpart%20list%20property%20using%20PNPJS%3C%2FLINGO-SUB%3E%3CLINGO-BODY%20id%3D%22lingo-body-877777%22%20slang%3D%22en-US%22%3E%3CP%3EThis%20is%20what%20I%20am%20left%20with%20for%20now.%20My%20this.lists%20object%20is%20still%20empty%20before%20it%20gets%20to%20the%20PropertyPaneDropdown%20object%20and%20I%20don't%20know%20what%20to%20do%20to%20fix%20that.%3C%2FP%3E%3CP%3E%26nbsp%3B%3C%2FP%3E%3CPRE%20class%3D%22lia-code-sample%20language-javascript%22%3E%3CCODE%3E%20%20protected%20fetchOptions()%3A%20IPropertyPaneDropdownOption%5B%5D%20%7B%0A%20%20%20%20var%20options%3A%20Array%3CIPROPERTYPANEDROPDOWNOPTION%3E%20%3D%20new%20Array%3CIPROPERTYPANEDROPDOWNOPTION%3E()%3B%0A%20%20%20%20sp.web.lists.select('ID'%2C%20'Title'%2C%20'DefaultViewUrl').orderBy('Title').get().then(function(data)%7B%0A%20%20%20%20%20%20for%20(let%20i%20%3D%200%3B%20i%20%26lt%3B%20data.length%3B%20i%2B%2B)%20%7B%0A%20%20%20%20%20%20%20%20options.push(%7B%0A%20%20%20%20%20%20%20%20%20%20key%3A%20data%5Bi%5D.Title%2C%0A%20%20%20%20%20%20%20%20%20%20text%3A%20data%5Bi%5D.Title%0A%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20return%20options%3B%0A%20%20%20%20%7D)%3B%0A%20%20%20%20return%20null%3B%0A%20%20%7D%0A%0A%20%20protected%20getPropertyPaneConfiguration()%3A%20IPropertyPaneConfiguration%20%7B%0A%0A%20%20%20%20if%20(!this.lists)%20%7B%0A%20%20%20%20%20%20this.lists%20%3D%20this.fetchOptions()%3B%0A%20%20%20%20%20%20this.onDispose()%3B%0A%20%20%20%20%7D%0A%0A%20%20%20%20return%20%7B%0A%20%20%20%20%20%20pages%3A%20%5B%0A%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20header%3A%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20description%3A%20this.description%0A%20%20%20%20%20%20%20%20%20%20%7D%2C%0A%20%20%20%20%20%20%20%20%20%20groups%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20groupName%3A%20'Properties'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20groupFields%3A%20%5B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20PropertyPaneDropdown('list'%2C%20%7B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20label%3A%20'List'%2C%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20options%3A%20this.lists%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%7D)%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%20%20%20%20%5D%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%5D%0A%20%20%20%20%7D%3B%0A%20%20%7D%3C%2FIPROPERTYPANEDROPDOWNOPTION%3E%3C%2FIPROPERTYPANEDROPDOWNOPTION%3E%3C%2FCODE%3E%3C%2FPRE%3E%3C%2FLINGO-BODY%3E
Contributor

I am writing a simple web part. It takes a property of "List". The user will pick the list from a dropdown. I am using the tutorial found here:

https://www.sharepointnutsandbolts.com/2016/09/sharepoint-framework-spfx-web-part-properties-dynamic...

 

I have the following function that uses PNPJS to return an array of the lists on the site.

 

  protected fetchLists(): Array<IPropertyPaneDropdownOption> {
    let options: Array<IPropertyPaneDropdownOption> = new Array<IPropertyPaneDropdownOption>();
    sp.web.lists.select('ID', 'Title', 'DefaultViewUrl').get().then(function(data) {
      for (let i = 0; i < data.length; i++) {
        if (data[i].DefaultViewUrl.includes('/Lists/')) {
          options.push({
            key: data[i].Title,
            text: data[i].Title,
          });
        }
      })
      console.log(options);
    });
    return options;
  }

 

The above function is called in the getPropertyPaneConfiguration with the line: 
let lists: Array<IPropertyPaneDropdownOption> = this.fetchLists();

 

  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {
    let lists: Array<IPropertyPaneDropdownOption> = this.fetchLists();
    return {
      pages: [
        {
          header: {
            description: this.description
          },
          groups: [
            {
              groupName: 'Properties',
              groupFields: [
                PropertyPaneDropdown('list', {
                  label: 'List',
                  options: lists
                }),
                PropertyPaneTextField('field', {
                  label: 'Field'
                })
              ]
            }
          ]
        }
      ]
    }  
  }

 

 

The problem is the sp.web.lists... call is seen by the editor as not ways returning a value. I have tried to use the .then(function() {}) to return the array but the IDE still says not all paths return a value. How can I satisfy the IDE and still always get a return array (even if it is empty)?

4 Replies

So I made the following changes. I added the catch method and put another return in there but the IDE still doesn't think that my code always returns as a value.

 

  protected fetchLists(): Array<IPropertyPaneDropdownOption> {
    let options: Array<IPropertyPaneDropdownOption> = new Array<IPropertyPaneDropdownOption>();
    sp.web.lists.select('ID', 'Title', 'DefaultViewUrl').orderBy('Title').get().then(function(data) {
      for (let i = 0; i < data.length; i++) {
        if ((data[i].DefaultViewUrl.includes('/Lists/')) && 
        (
          (data[i].Title != 'SharePointHomeCacheList') || 
          (data[i].Title != 'TaxonomyHiddenList')
        )) {
          options.push({
            key: data[i].Title,
            text: data[i].Title,
          });
        }
      }
      return options;
    }).catch(function(e) {
      return options;
    });
  }

 

I also tried to change the return object of the function to "any", and that will compile but the list doesn't come out in the right format for the getPropertyPaneConfiguration method.
I have concluded that my problem is asynchronous code execution. I have two functions that return a value. function A calls function B and needs to wait for the reply before it continues. This may be more complicated because function B calls another function with a callback. That I can't figure out is how to make function B a callback when I don't control when function A gets called.

This is what I am left with for now. My this.lists object is still empty before it gets to the PropertyPaneDropdown object and I don't know what to do to fix that.

 

  protected fetchOptions(): IPropertyPaneDropdownOption[] {
    var options: Array<IPropertyPaneDropdownOption> = new Array<IPropertyPaneDropdownOption>();
    sp.web.lists.select('ID', 'Title', 'DefaultViewUrl').orderBy('Title').get().then(function(data){
      for (let i = 0; i < data.length; i++) {
        options.push({
          key: data[i].Title,
          text: data[i].Title
        })
      }
      return options;
    });
    return null;
  }

  protected getPropertyPaneConfiguration(): IPropertyPaneConfiguration {

    if (!this.lists) {
      this.lists = this.fetchOptions();
      this.onDispose();
    }

    return {
      pages: [
        {
          header: {
            description: this.description
          },
          groups: [
            {
              groupName: 'Properties',
              groupFields: [
                PropertyPaneDropdown('list', {
                  label: 'List',
                  options: this.lists
                })
              ]
            }
          ]
        }
      ]
    };
  }