Picklists are a great way to customize Salesforce objects, providing a reusable and admin-friendly solution with built-in validation. However, accessing picklist values programmatically is not straightforward, and it’s important to understand the various techniques and pitfalls involved. In this post, we’ll discuss different methods for accessing picklist values in Apex and Lightning Web Components. We’ll cover their limitations, and we’ll leave you with best practices for selecting the right approach (depending on your use case).
Using picklists in Apex
A common practice for accessing picklist values from a trigger or a server controller is to use dynamic Apex. Dynamic Apex isn’t limited to dynamic SOQL, in fact it lets you analyze objects and fields programmatically with methods from the Schema namespace. With this technique, you can answer questions like: What are the fields of an object? What is the type of a particular field? Or, what are the possible values of a picklist field?
The following code sample shows how you can retrieve picklist values for the “Industry” field of the “Account” object as a list of Schema.PicklistEntry using getDescribe()
and getPicklistValues():
While this approach is functional and simple, it has three important limitations:
- It relies on hard-coded object and field names.
- It returns values that include inactive picklist values.
- It doesn’t handle values for specific record types.
You can easily address the first two issues by writing a generic helper method that works with any field and that only returns active picklist entries:
The above snippet is a naive implementation with no caching, but you can see that things start to get slightly more verbose.
Another important consideration (that’s often overlooked) when accessing picklists values is the fact that admins can restrict picklist values for a given record type. The dynamic Apex approach that we just covered does not support this scenario. If you need to work with picklist values for specific record types, you’ll need to do a callout to this UI API endpoint:
For the sake of brevity, we won’t show the full Apex code in this post, but you can check out an implementation in the PicklistUtils repository. This project provides a reusable PicklistUtils
utility class with full code coverage and caching. PicklistUtils
helps you handle all picklist use cases with simple calls:
Using picklists in Lightning Web Components
If you are building a Lightning Web Component that relies on picklist values, you could call a custom Apex controller to retrieve those values with the methods that we just described. But the good news is that there’s a simpler solution. You can avoid Apex altogether by calling directly the UI API with the getPicklistValues wire adapter from the lightning/uiObjectInfoApi
module.
The getPicklistValues
adapter retrieves all picklist values for a given record type and field name. Using the adapter is interesting for performance reasons because it benefits from the Lightning Data Service cache. Additionally, this also reduces the amount of Apex code you have to maintain and test (no need for a custom Apex controller).
Here’s an example of how you can retrieve all picklist values for the Industry field of the Account object:
For a complete example of how to use getPicklistValues
in combination with other UI API adapters, see the Retrieving Picklist Values Without Using Apex blog post.
Closing words
This concludes our tour of the different techniques for accessing picklist values in Apex and Lightning Web Components. Here’s a recap of the best practices we covered in this post:
- Use dynamic Apex when working with records with no record type.
- Use UI API callouts when working with record types in Apex.
- Use the UI API getPicklistValues wire adapter when working with Lightning Web Components.
- Use an Apex utility class like PicklistUtils to avoid code duplication.
About the author
Philippe Ozil is a Principal Developer Advocate at Salesforce, where he focuses on the Salesforce Platform. He writes technical content and speaks frequently at conferences. He is a full stack developer and enjoys working on DevOps, robotics, and VR projects. Follow him on Twitter @PhilippeOzil or check his GitHub projects @pozil.