Free computer code on screen

Various Approaches For Binding Picklist Values In Lightning Web Components LWC

This blog post delves into diverse techniques for binding picklist values within LWC and their application in the development process.

Within this LWC component, three distinct picklist fields—Type, Industry, and Rating—are utilized. Let’s delve into how picklist values have been bound for these fields.

1. Employing the UI Object Info API

The initial method for binding picklist values involves utilizing the UI Object Info API. This API enables the retrieval of metadata information pertaining to an object, allowing access to the list of picklist values for a specific field. In this instance, the provided LWC component utilizes the Metadata API to bind picklist values for the Type field sourced from the Account Object.

To leverage the UI Object Info API, we start by importing the ‘getPicklistValues’ function from the ‘lightning/uiObjectInfoApi’ module. Subsequently, we utilize the ‘@wire’ decorator to wire this function to our component. Within the wired property, we map the data values into an array of options, utilizing this array to populate the lightning-combobox component.

Sample Code:

The initial method for binding picklist values involves utilizing the UI Object Info API. This API enables the retrieval of metadata information pertaining to an object, allowing access to the list of picklist values for a specific field. In this instance, the provided LWC component utilizes the Metadata API to bind picklist values for the Type field sourced from the Account Object.

To leverage the UI Object Info API, we start by importing the 'getPicklistValues' function from the 'lightning/uiObjectInfoApi' module. Subsequently, we utilize the '@wire' decorator to wire this function to our component. Within the wired property, we map the data values into an array of options, utilizing this array to populate the lightning-combobox component.

Sample Code:

Below are the pros and cons of this approach –

Advantages –

  • Simplicity: The lightning/uiObjectInfoApi module offers a straightforward and declarative approach to accessing picklist values through a standardized API. This simplicity can facilitate developers in customizing or maintaining your application with greater ease.
  • Up-to-Date Information: Utilizing the standard API ensures continuous access to the most current picklist values, eliminating the need for manual updates within an Apex class.
  • Consistency: Employing the standard API guarantees uniform picklist values across your organization. It also ensures that these values comply with any custom business logic or validation rules configured on the picklist field.
  • Record Type Support: If your object employs record types, this API enables the retrieval of picklist values based on the record type assignments within your organization.
  • Wide Support: This functionality is supported for all custom objects and most standard objects.

Drawbacks –

  • Performance: Depending on the complexity of your application and the number of picklist fields that need to be retrieved, using the lightning/uiObjectInfoApi module could impact performance by requiring additional client-server round trips.
  • API Limits: Depending on the number of API calls you make and the number of picklist fields that need to be retrieved, you may run into API limits or incur additional costs if you are using a third-party API provider.
  • Limited Flexibility: While the lightning/uiObjectInfoApi module provides a simple way to retrieve picklist values, it may not offer the same level of flexibility or control as retrieving picklist values from an Apex class. For example, you may not be able to dynamically change the available picklist values based on certain conditions or add custom logic to handle the selected value.
  • Not supported for external objects and some of the standard objects are also not supported , make sure to check these salesforce documentation links before implementing- Salesforce Objects Supported by lightning/ui*Api Modules – Salesforce Lightning Component Library & All Supported Objects | User Interface API Developer Guide | Salesforce Developers

2. Utilizing Hardcoded Values in JavaScript for Picklist Options

The secondary method to bind picklist values involves using hardcoded values. Within the provided LWC component, this method is employed to bind the picklist values for the Industry field sourced from the Account Object.

To utilize hardcoded values, we straightforwardly create an array of options within our component and employ it to populate the lightning-combobox component.

JS - 
// Define an array of industry options
    industryOptions = [
        { label: 'Agriculture', value: 'Agriculture' },
        { label: 'Apparel', value: 'Apparel' },
        { label: 'Banking', value: 'Banking' },
        { label: 'Biotechnology', value: 'Biotechnology' },
        { label: 'Chemicals', value: 'Chemicals' }
    ];
HTML -
<lightning-combobox label="Industry" value={accountIndustry} options={industryOptions}
                onchange={handleAccountIndustryChange}></lightning-combobox>

Below are the pros and cons of this approach –

Downsides –

  • Lack of server-side validation : Due to lack of server-side validation, it may cause data inconsistencies if the pick list options only rely on JavaScript, and the options do not match the data stored on the server.s.
  • Potential security risks: Improper sanitization of pick list options defined in JavaScript could lead to potential security vulnerabilities, such as cross-site scripting (XSS) attacks.

3. Employing Apex Controller

The third method to bind picklist values involves utilizing an Apex controller. Within the provided LWC component, this approach is employed to bind the picklist values for the Rating field sourced from the Account Object.

To utilize an Apex controller, we first define an Apex method responsible for returning the picklist values. Subsequently, we import this method into our LWC component using the ‘@salesforce/apex’ module. Then, utilizing the ‘@wire’ decorator, we wire the method to our component. Within the wired property, we map the data to an array of options, which is used to populate the lightning-combobox component.

JS -
// Import getRatingPicklistValues function from Apex controller
import getRatingPicklistValues from '@salesforce/apex/AccountController.getPicklistValues';
// Wire getRatingPicklistValues function from Apex controller to the component
    @wire(getRatingPicklistValues, {})
    // Define a wired property for rating picklist values
    wiredRatingPicklistValues({ error, data }) {
        // If data is returned from the wire function
        if (data) {
            // Map the data to an array of options
            this.ratingOptions = data.map(option => {
                return {
                    label: option.label,
                    value: option.value
                };
            });
        }
        // If there is an error
        else if (error) {
            // Log the error to the console
            console.error(error);
        }
    }
HTML -
<lightning-combobox label="Rating" value={accountRating} options={ratingOptions}
                onchange={handleAccountRatingChange}></lightning-combobox>
Apex - 
@AuraEnabled(cacheable=true)
    public static List<Map<String, String>> getPicklistValues() {
        List<Schema.PicklistEntry> entries = Account.Rating.getDescribe().getPicklistValues();
        List<Map<String, String>> values = new List<Map<String, String>>();
        for (Schema.PicklistEntry entry : entries) {
            Map<String, String> valueMap = new Map<String, String>();
            valueMap.put('label', entry.getLabel());
            valueMap.put('value', entry.getValue());
            values.add(valueMap);
        }
        return values;
    }

Below are the pros and cons of this approach –

Advantages –

Enhanced Control: Accessing picklist values from an Apex class grants greater control over their display and utilization within your application. This includes dynamic adjustments to available picklist values based on specific conditions or the incorporation of custom logic to manage selected values.

Improved Performance: Employing a cached, server-side call for retrieving picklist values enhances application performance by minimizing the number of client-server round trips necessary to obtain these values.

Versatility: Exposing a picklist values method through an Apex class enables its utilization across various components, pages, or even multiple applications. This facilitates code reusability and ensures a consistent user experience throughout your organization.

Downsides –

  • Maintenance: If picklist values change frequently, it may be more difficult to keep an Apex class up to date compared to using a standard picklist field in the UI. You would need to update the Apex class every time the picklist values change.No Support for Record Types – Currently there is no support for Getting Picklist values based on Record Type, you need to make your own logic to customize the options – Getting Picklist values based on Record Type | IdeaExchange (salesforce.com)

Below is the complete sample code, where we showed the below 3 ways –

  • Bind Type field by Using UI Object Info APIBind Industry field by Using Hardcoded values in JS for PickList OptionsBind Rating field by Using Apex Controller

HTML

<template>
    <lightning-card title="Account Form">
        <div class="slds-m-around_medium">
            <lightning-combobox label="Type" value={accountType} options={typeOptions}
                onchange={handleAccountTypeChange}>
            </lightning-combobox>
            <lightning-combobox label="Industry" value={accountIndustry} options={industryOptions}
                onchange={handleAccountIndustryChange}></lightning-combobox>
            <lightning-combobox label="Rating" value={accountRating} options={ratingOptions}
                onchange={handleAccountRatingChange}></lightning-combobox><br />
            Selected Type - {accountType} <br />
            Selected Industry - {accountIndustry} <br />
            Selected Rating - {accountRating}
        </div>
    </lightning-card>
</template>

JS

// Import LightningElement and wire decorator from LWC module
import { LightningElement, wire } from 'lwc';
// Import getPicklistValues function from uiObjectInfoApi module
import { getPicklistValues } from 'lightning/uiObjectInfoApi';
// Import getRatingPicklistValues function from Apex controller
import getRatingPicklistValues from '@salesforce/apex/AccountController.getPicklistValues';
// Import constant TYPE_FIELD from Account schema
import TYPE_FIELD from '@salesforce/schema/Account.Type';
export default class AccountForm extends LightningElement {
    // Initialize properties for the component
    accountType = ''; // Set default value for accountType
    accountIndustry = ''; // Set default value for accountIndustry
    accountRating = ''; // Set default value for accountRating
    typeOptions = []; // Initialize typeOptions as an empty array
    ratingOptions = []; // Initialize ratingOptions as an empty array
    // Define an array of industry options
    industryOptions = [
        { label: 'Agriculture', value: 'Agriculture' },
        { label: 'Apparel', value: 'Apparel' },
        { label: 'Banking', value: 'Banking' },
        { label: 'Biotechnology', value: 'Biotechnology' },
        { label: 'Chemicals', value: 'Chemicals' }
    ];
    // Wire getPicklistValues function from uiObjectInfoApi module to the component
    @wire(getPicklistValues, {        
        recordTypeId: '012000000000000AAA', // Specify record type ID , if no record type is there specify default record type
        fieldApiName: TYPE_FIELD // Specify field API name
    })
    // Define a wired property for type picklist values
    wiredTypePicklistValues({ error, data }) {
        // If data is returned from the wire function
        if (data) {
            // Map the data values to an array of options
            this.typeOptions = data.values.map(option => {
                return {
                    label: option.label,
                    value: option.value
                };
            });
        }
        // If there is an error
        else if (error) {
            // Log the error to the console
            console.error(error);
        }
    }
    // Wire getRatingPicklistValues function from Apex controller to the component
    @wire(getRatingPicklistValues, {})
    // Define a wired property for rating picklist values
    wiredRatingPicklistValues({ error, data }) {
        // If data is returned from the wire function
        if (data) {
            // Map the data to an array of options
            this.ratingOptions = data.map(option => {
                return {
                    label: option.label,
                    value: option.value
                };
            });
        }
        // If there is an error
        else if (error) {
            // Log the error to the console
            console.error(error);
        }
    }
    // Define a method to handle changes to the account type
    handleAccountTypeChange(event) {
        // Set the account type to the selected value
        this.accountType = event.target.value;
    }
    // Define a method to handle changes to the account industry
    handleAccountIndustryChange(event) {
        // Set the account industry to the selected value
        this.accountIndustry = event.target.value;
    }
    // Define a method to handle changes to the account rating
    handleAccountRatingChange(event) {
        // Set the account rating to the selected value
        this.accountRating = event.target.value;
    }
}

Apex

public with sharing class AccountController {
    /**
    * Retrieves the picklist values for the Rating field of the Account object.
    * @return A list of maps, where each map contains the label and value of a picklist value.
    */
    @AuraEnabled(cacheable=true)
    public static List<Map<String, String>> getPicklistValues() {
        // Retrieve the picklist values for the Rating field of the Account object.
        List<Schema.PicklistEntry> entries = Account.Rating.getDescribe().getPicklistValues();
        // Create a list to hold the label and value of each picklist value.
        List<Map<String, String>> values = new List<Map<String, String>>();
        // Loop through the picklist values and add the label and value to the list.
        for (Schema.PicklistEntry entry : entries) {
            // Create a map to hold the label and value of the picklist value.
            Map<String, String> valueMap = new Map<String, String>();
            // Add the label and value to the map.
            valueMap.put('label', entry.getLabel());
            valueMap.put('value', entry.getValue());
            // Add the map to the list.
            values.add(valueMap);
        }
        // Return the list of maps.
        return values;
    }