4

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>

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;
}
  • 1
    for starters, you might want to change your attribute types to MAP instead of Object =) it is recommended – glls Mar 23 '18 at 15:02
  • Then I could just change my APEX to a map and it would solve my problem? – Chance Mar 23 '18 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 Mar 23 '18 at 15:08
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}"/>
  • 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 Mar 23 '18 at 15:38
  • 1
    @Chance See the PS. – Keith C Mar 23 '18 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 Mar 23 '18 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 Mar 23 '18 at 16:15
  • 1
    @Chance Yes the syntax is key1 => value1, key2 => value2. – Keith C Mar 23 '18 at 16:23

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.