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
- Pass in default value for the attribute (obtained from another component)
- 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
If I remove the
value="{!v.State}"
from thelightning: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 attributeIf I hardcode the States it works as expected but I cannot hard code them..
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?
ui:inputSelect
instead oflightning:select
?