lightning:select - Set default value based on sObject List from apex controller

  • Trying to populate an lightning attribute if a single record exists and if multiple records exists would like to provide the user a select list to choose the record then set the attribute.

    I cannot seem to get the lightning:select to get its value to be set:


    <aura:component description="Account_Selection" controller="MyController">
            <!-- Handle component initialization in a client-side controller -->
            <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
            <!-- The list of accounts to display -->
            <aura:attribute name="accounts" type="Account[]"/>
            <lightning:select aura:id="a_opt" name="a_opt" label="Accounts"  onchange="{!c.onSelectChange}">
                <aura:iteration items="{!v.accounts}" var="account">
                    <option value="{!account.Id}">{!account.Name}</option>


        doInit : function(component, event, helper) {
        onSelectChange : function(component, event, helper) {
            // Print out the selected value
            var selected = component.find("a_opt").get("v.value");
            console.log('@@@@@@@: ' + selected);


        getAccounts : function(cmp) {
             var action = cmp.get("c.getAccounts");
             action.setCallback(this, function(response){
                var state = response.getState();
                if (state === "SUCCESS") {
                    cmp.set("v.accounts", response.getReturnValue());
                    var sel = cmp.find('a_opt');

    Now, the select DOES show the available select options but I cannot for the life of me get the value to be set via the code.

    The above component is within a parent component as so:

    <c:Account_Selection aura:id="a_selection"/>

    The parent component has an attribute

    <aura:attribute name="accountId" type="Id"/>

    What I would like to happen:

    1. If only one account record returned from the apex controller, set the value of the accountId attribute to the Id of that record
    2. If multiple accounts found, set the default value of the select list to a specific value and set the attribute value
    3. If user selects a value then set the value of the attribute

    I have tried everything I can think of searched but cannot get it to work. The select list has all the options but the first value seems to always be selected regardless of the value I attempt to set.

    The outPutText does not have any value despite explicitly setting it from the component..

    Any ideas how to make this work?


    I think the issue is the "cmp" is not the lightning component it is the apex controller? How do i get a reference back to the component on the callback?

    why are you manually trying to select using cmp.find() instead of using `value` attribute in the lightning:select point to `v.accountId`?

    I think `cmp` is a reference to the component. Are you having the problem in the `getAccountss` helper function? (is the addition s a typo?)

    Assuming the account Id is a valid, 18-character ID, it should work. If you're using just 15-character ID values, it won't work. Does that help?

    Solved it... One sec.

    @PhilHawthorn - Was a typo in the question. When I pass in Component from doInit and hardcode the values it works properly

    @Praveen - I will see how well that works. I am essentially trying to default the value if only one option and allow select if multiple options. If only one option the select will be hidden. As to the Why, I am still learning lol so seeing how everything works in relation to the lifecycle....This is not your momma's visualforce anymore.

  • sfdcfox

    sfdcfox Correct answer

    5 years ago

    Setting the options doesn't actually cause the rendering to happen. So, the value you're setting is ignored because it isn't valid at the time. The solution is to use another callback post-rendering. Here's an example app I wrote that demonstrates this:

    <aura:application extends="force:slds" controller="LightningAccountController">
        <aura:attribute name="accounts" type="Account[]" />
        <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
        <lightning:select label="Choose 1" name="a_opt" aura:id="a_opt" onchange="{!c.change}">
            <aura:iteration items="{!v.accounts}" var="account">
                <option value="{!account.Id}">{!account.Name}</option>

    // Controller
        doInit: function(component, event, helper) {
            // Request from server
            var action = component.get("c.getAccountList");
            action.setCallback(this, function(result){
                var accounts = result.getReturnValue();
                component.set("v.accounts", accounts);
                // Let DOM state catch up.
                    $A.getCallback( function() {
                        // Now set our preferred value
                        component.find("a_opt").set("v.value", accounts[4].Id);

    // Apex class
    global class LightningAccountController {
        @AuraEnabled global static Account[] getAccountList() {
            return [SELECT Name FROM Account LIMIT 10];

    I had an inkling it was a rendering issue. Will try it out later this evening but I am sure it will work...Thank you very much!

    @Eric It's my pleasure. I learned something new today as well.

    It is wierd because if I hardcode the values and do not do the enque action it works as expected. If you look at the example here (replacing the UI with Lightning NS): - it works as expected, but if I pass in the sObject List and call the "loadOptions" from the callback and modify to use the sObjectList it does not set the value. Weird.....If you want me to update question with this example let me know.

    is the `settimeout` part a "guess" or could dom delays or something affect this guess and cause it to not set the value? And can you say frustrated. About ready to drop all this multiple components thing as setting values on the parent component from the child takes more code than just placing the child component code directly on the parent.....maybe I am missing something.

    @Eric JavaScript is a single-threaded model, so the timing should definitely be okay, even if rendering takes a lot of time. I do find it curious that the value isn't set right without the callback, though, because the documentation basically says "hear, this should work." So, either we have a bug, or we have a documentation error (that never happens... right?). Maybe we should try and get an authoritative answer from Dev Support?

    as documented it works. But if you call the loadoptions from the callback of the call to the apex controller (getAccounts) and pass in the results as opts to the method it does not. Make sense? Maybe I will post up an example in my question when I get back home.

    @Eric I get what you mean... Somehow, the callback seems to need time to do rendering. I think it's a limitation of callbacks, although the docs don't seem to explicitly say that. See Modifying Components Outside the Framework Lifecycle, which was the inspiration/source of my answer.

License under CC-BY-SA with attribution

Content dated before 7/24/2021 11:53 AM