8

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?

  • I suppose you could dynamically create it after the server call... Or just do as I did and roll thine own. It's nice to have full control of the component that you've built yourself. – Caspar Harmer Feb 3 '17 at 3:52
  • @CasparHarmer - Yea, I thought of that but it introduces dependencies that are deeper than simply adding the second attribute. It is a shame that the UI/Lightning input components are essentially useless (from my experience so far)... Easier to just use regular html elements. Hopefully they become more robust over time but for now they offer little benefit over an SLDS styled input. – Eric Feb 3 '17 at 4:08
  • @Eric Any luck with ui:inputSelect instead of lightning:select? – Praveen Feb 3 '17 at 19:12
  • @Praveen - Nope, same issue. – Eric Feb 3 '17 at 19:36
20

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

<option value="{!st}" selected="{!st==v.state}">{!st}</option>
  • 2
    seems to easy but it appears to work. Thank you. In all the bugs and unexpected things I have found with lightning component I cannot believe it does work but hey......I'll take it – Eric Feb 4 '17 at 7:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.