5

Sorry guys. I am really struggling with how to return the options from my server controller in a way that can be used.

How do I set the label:value pair in javascript? I am getting results into the attribute, but lightning:select is not able to read the data. I assume that is because it cannot make sense of the label:value pair since I am passing an object?

If anyone could even just point me to a good example of how to do this I would be appreciative. I was not able to find a good example on my own. Here is what I have so far:

Component

    <!-- list to hld the IP record types to be used if a record is created -->
    <aura:attribute name="ipRecordTypes" type="Object" access="public"/>
    <aura:attribute Name="selRecType" type="object"  access="public" />

    <lightning:select aura:id="selectRecType" name="selectRecType" label="Record Type" required="true" value="{!v.selectIPRecordType}" messageWhenValueMissing="You must define the record type of the new IP">
     <aura:iteration items="{!v.ipRecordTypes}" var="item">
         <option text="{!item.label}" selected="{item.selected}"/>
     </aura:iteration>
    </lightning:select>

Controller

    getRecordTypes : function(component){//------------------------------------------------------
        console.log('getRecordTypes helper starting...');
        
        //calls InventionResearcherController.getInventionContacts
        var action = component.get('c.getRecordTypes');
        
        // Set up the callback
        action.setCallback(this, $A.getCallback(function (response) {
            var state = response.getState();
            var resultsToast = $A.get("e.force:showToast");
            if(state === "SUCCESS"){
                //if successful stores query results in ipRecordTypes
                var recordTypes = response.getReturnValue();
                console.log('getRecordTypes returned: ' +recordTypes);                
                
                component.set('v.ipRecordTypes', response.getReturnValue());
            } else if (state === "ERROR") {
                //otherwise write errors to console for debugging
                alert('Problem with connection. Please try again. Error Code: relIPViewHelper.getIPList.action.setCallback');
                resultsToast.setParams({
                    "title": "Error",
                    "message": "Invention contacts failed to load due to: " + JSON.stringify(result.error)
                });
                resultsToast.fire();
                var errors = response.getError();
                console.error(errors);
            }
        }));
        $A.enqueueAction(action);

Server side

    @AuraEnabled
    public static List<RecordType> getRecordTypes() {
        System.debug('getRecordTypes starting...');
        return [SELECT id, name FROM RecordType WHERE SobjectType = 'IP__c'];
    }


OK, thanks to the help of @KeithC I was able to get it to work. This is a very simple solution and I think posting the full answer will help other beginner devs like myself.

Here is the updated code:

Component

    <!-- list to hld the IP record types to be used if a record is created -->
    <aura:attribute name="ipRecordTypes" type="List" access="public"/>
    <aura:attribute Name="selRecType" type="String"  access="public" />

    <lightning:select aura:id="selectRecType" name="selectRecType" label="Record Type" required="true" 
                    value="{!v.selRecType}" onchange="{!c.showRecType}" 
                    messageWhenValueMissing="You must define the record type of the new IP">
    <option value="">-- Please Select --</option>
    <aura:iteration items="{!v.ipRecordTypes}" var="item">
        <option text="{!item.label}" value="{!item.value}" selected="{item.selected}"/>
    </aura:iteration>
</lightning:select>

Controller

    doInit : function(component, event, helper) {
        //[other code]
        
        //this block of code to get the IP Record types
        helper.getRecordTypes(component);
    },

    showRecType : function(component, event, helper) {
        console.log('The selected Record Type is: ' +component.get("v.selRecType"));
    }

helper

    getRecordTypes : function(component){//------------------------------------------------------
        console.log('getRecordTypes helper starting...');
        
        //calls InventionResearcherController.getInventionContacts
        var action = component.get('c.getRecordTypes');
        
        // Set up the callback
        action.setCallback(this, $A.getCallback(function (response) {
            var state = response.getState();
            var resultsToast = $A.get("e.force:showToast");
            if(state === "SUCCESS"){
                //if successful stores query results in ipRecordTypes
                var recordTypes = response.getReturnValue();
                console.log('getRecordTypes returned: ' +recordTypes);                
                
                component.set('v.ipRecordTypes', response.getReturnValue());
            } else if (state === "ERROR") {
                //otherwise write errors to console for debugging
                alert('Problem with connection. Please try again. Error Code: relIPViewHelper.getIPList.action.setCallback');
                resultsToast.setParams({
                    "title": "Error",
                    "message": "Invention contacts failed to load due to: " + JSON.stringify(result.error)
                });
                resultsToast.fire();
                var errors = response.getError();
                console.error(errors);
            }
        }));
        $A.enqueueAction(action);

Server side Controller

    @AuraEnabled
    public static List<Map<String, String>> getRecordTypes() {
        System.debug('getRecordTypes starting...');
        
        List<Map<String, String>> items = new List<Map<String, String>>();
        for (RecordType rt : [SELECT id, name FROM RecordType WHERE SobjectType = 'IP__c']) {
                items.add(new Map<String, String>{'value' => rt.Id, 'label' => rt.Name});
            }
        return items;
    }
3
  • 1
    for starters, you might want to change your attribute types to MAP instead of Object =) it is recommended
    – glls
    Commented Mar 23, 2018 at 15:02
  • Then I could just change my APEX to a map and it would solve my problem?
    – Chance
    Commented Mar 23, 2018 at 15:04
  • i havent gon through your code yet, just noticed your attribute types which are not recommended anymore, you can read Object Types for more details, changing that would be a good start
    – glls
    Commented Mar 23, 2018 at 15:08

1 Answer 1

6

One way to return an array of objects where the object fields have the keys of "value" and "label" as required by your component is:

@AuraEnabled
public static List<Map<String, String>> getRecordTypes() {

    System.debug('getRecordTypes starting...');

    List<Map<String, String>> items = new List<Map<String, String>>();
    for (RecordType rt : [
            SELECT id, name
            FROM RecordType
            WHERE SobjectType = 'IP__c'
            ]) {
        items.add(new Map<String, String>{'value' => rt.Id, 'label' => rt.Name});
    }
    return items;
}

Or if you are doing a lot of this, you can create your own class as described in Why is SelectOption not supported by JSON class?.

PS

This markup to match this is:

<option text="{!item.label}" value="{!item.value}"/>
7
  • So this gets the options to show up in lightning:select, but it returns the values as undefined. Here are some logs: getRecordTypes returned: [object Object],[object Object] and then: The selected Record Type is: undefined
    – Chance
    Commented Mar 23, 2018 at 15:38
  • 1
    @Chance See the PS.
    – Keith C
    Commented Mar 23, 2018 at 15:43
  • This worked great after I fixed a few things in the component, too. I will edit it so others can get the full solution.
    – Chance
    Commented Mar 23, 2018 at 15:57
  • 1
    @Chance Its a mechanism in Apex that makes initializing maps more convenient - see e.g. force201.wordpress.com/2010/04/12/collection-initialization.
    – Keith C
    Commented Mar 23, 2018 at 16:15
  • 1
    @Chance Yes the syntax is key1 => value1, key2 => value2.
    – Keith C
    Commented Mar 23, 2018 at 16:23

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .