Wednesday 21 September 2016

Web part properties – dynamically populate Dropdown options in SPFx


When building web parts in the SharePoint Framework (SPFx), there’s often a need to implement custom web part properties – this allows the user to configure your web part in the way they need. Microsoft provide a set of core controls to use for this, one of which is the dropdown control (PropertyPaneDropdown). My previous article covered the basics of using the dropdown control (and others), but sometimes you need to go beyond providing a static ‘hard-coded’ set of options in the dropdown – in this post, we’ll show how to populate the control dynamically.

For reference, this article is part of the following series around web part properties:

Recap - populating the Dropdown control with static options

As a reminder, to provide a simple static list of options we use code like this in the getPropertyPaneConfiguration method:

PropertyPaneDropdown('dropdownProperty', {
                  label: 'This is the label',
                  options: [
                    { key: 'Red', text: 'Red' },
                    { key: 'Green', text: 'Green' },
                    { key: 'DarkBlue', text: 'Dark blue' }

But as we’re saying, having a static set of options often isn’t enough – we need to fetch them from somewhere when the user edits the web part. So let’s move on to that.

Dynamically populating the list – a simple example

Let’s start simple – in the code below, we change things so that the options are fetched from a separate method. I’m just showing the basics of using code to populate the list, but so far we’re not talking to SharePoint or another data source to get them:

So, we’re simply building an array of the appropriate object (IPropertyPaneDropdownOption) and returning it.

Dynamically populating the list – by fetching data from SharePoint

Things get a little more complicated when we need to talk to SharePoint, or make some other kind of async call to get the data. If we simply amend the previous code to call SharePoint (using spHttpClient or similar), we’ll find that we may have timing issues – our async method will fire, but getPropertyPaneConfiguration method continues to execute during this time, and the collection of items is empty. Some time later the collection will be populated, but it’s too late for our dropdown control.

The trick is to obtain the data, and then refresh the property pane by calling the onDispose() method of the web part. This patterns ensures that you are not delaying the load of the entire page or web part property pane, but that the UI is refreshed once the dynamic data has been fetched.
NOTE: in previous SPFx builds, the guidance was to use the OnInit() method of the web part – however, that led to problems in some scenarios, so that guidance has been updated to the pattern described here. For other things, OnInit() can be your friend though – just not necessarily for web part property pane work.

In this example we populate the dropdown with the SharePoint lists in the current site. We do this with an async REST call to SharePoint, which uses Promises in the code structure:

..and then in the getPropertyPaneConfiguration method, we kick-off the call to fetch the data at the beginning, and then in the control declaration we simply set the options property to our variable holding the array:

So that’s it – a web part property control using dynamic options!


The web part property model in SPFx is quite powerful, and is a great advantage of the SharePoint Framework compared to the classic “cloud-friendly web part” approach of using a Script Editor and some JavaScript. It’s possible to run code to build your web part property pane, but just be aware of timing and lifecycle issues. The onDispose method in a SPFx web part can be used to refresh the property pane once any additional code you have has executed.

1 comment:

Jason Dunbar said...

Thanks for the guide Chris. I recognise that this is an old post, but for those of you coming here and wondering why the property pane refresh isn't working, you'll want to reference the documentation here for the updated way of doing it -