[SalesForce] Unable to set lightning:select value when using dynamically created options

Original question: lightning:select – Set default value based on sObject List from apex controller

Now to extend upon that question I am trying to do the following

  1. Pass in default value for the attribute (obtained from another component)
  2. Set the value of the select to be the default value

Note: In this example I am explicitly setting the value to reduce code. Getting the value from the controller is not the problem

Important If I do not use the value attribute on the lightning:select I am able to set the value of the element just fine, this only happens when using the value attribute on the element.

Now the reasons why I need this to work are unimportant the important part is that I need to be able to set the value of the element which is bound to the attribute..

Component (does not work)

<aura:component description="myProblemComponent" controller="myProblemController" implements="flexipage:availableForAllPageTypes">

    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>

    <aura:attribute name="State" type="String" default="Ohio"/> <!-- Set default here because in this use case the initial value is passed into the component -->
    <aura:attribute name="billingStates" access="public" type="String[]"/>

                <div class="slds-form-element">
                    <label class="slds-form-element__label" for="text-input-01">Input Label</label>
                    <div class="slds-form-element__control">
                        <lightning:select aura:id="state_opt"
                                          value="{!v.State}"
                                          name="state_opt" label="State"
                                          required="true">
                            <option value="">...Select a State...</option>
                            <aura:iteration items="{!v.billingStates}" var="st">
                                <option value="{!st}">{!st}</option>
                            </aura:iteration>

                        </lightning:select>
                    </div>
                </div>

</aura:component>

Component modification that works

<aura:attribute name="State" type="String"/>
<aura:attribute name="defaultState" type="String" default="Ohio"/>

Component Controller

({
    doInit: function (component, event, helper) {

        var action = component.get("c.getStates");

        action.setCallback(this, function (a) {

            component.set("v.billingStates", a.getReturnValue());

            window.setTimeout(
                $A.getCallback(function () {
                    console.log('Ohio');
                    component.set('v.State','Ohio'); //This does not update the value of the select
                    component.find('state_opt').set('v.value','Ohio'); // this does not update the value of the select
                })
            );

        });

        $A.enqueueAction(action);

    }
})

Component controller modification that works

component.set('v.State',component.get('v.defaultState'));

Apex Controller

public class myProblemController {
    @AuraEnabled
    public static List<String> getStates() {

        return new List<String>{'Texas','Ohio'};

    }

}

What I Expect to happen

When the component loads the select list is showing 'Ohio' as the selected option. Since the component is used in other component it is likely that the default value is passed in even though the dynamic options have not loaded yet

What Happens

The select is showing '…Select a State…' as the selected option even though the State attribute is set to 'Ohio'. Since it is already set to 'Ohio' setting it again does not trigger the redrawing of the select element

Mitigation

  1. If I remove the value="{!v.State}" from the lightning:select the select shows 'Ohio' as expected, however this causes me an issue when I re-render the select since it is no longer bound to an attribute

  2. If I hardcode the States it works as expected but I cannot hard code them..

  3. Working but not ideal (see modifications above) if I add a second attribute to the component and use that for the default value then on init set the value of State attribute the value of the second attribute it works.

This makes me understand that since the options are not yet loaded, when the State attribute is loaded with a default value it does not match an option so it is not set. Then when the init is done, setting the value does not trigger the change event on the element thus the element is not updated

Question

Any idea how to set the value of the lightning select in this scenario without the additional overhead (just seems wrong) and have it display properly?

Best Answer

You should make the option element selected explicitly. Can you not try as below.

<option value="{!st}" selected="{!st==v.state}">{!st}</option>
Related Topic