0

I am trying to set a radio button's options dynamically. I'm first constructing a wrapper list in my first component and passing the list to another component where I'm displaying the values.

Apex Controller:

@AuraEnabled
    public static Map<String,List<surveywrapper>> Questions(String partnerName,List<String>selectedCommitteeList){
        Map<String,List<surveywrapper>> surveyMap = new Map<String,List<surveywrapper>>();
        for(Survey_Question_Bank__c survey: [Select Id,Mandatory__c,Question__c,Question_Literal_Backend__c,Section__c,Sub_Section__c FROM Survey_Question_Bank__c ORDER BY Section__c DESC]){
            surveywrapper wrap = new surveywrapper();
            wrap.question = survey.Question__c;
            if(survey.Question_Literal_Backend__c == 'Committee'){
                wrap.optionList = selectedCommitteeList;
            }else{
                wrap.optionList.add('Strongly Disagree');
                wrap.optionList.add('Agree');
            }

            if(surveyMap.containsKey(survey.Section__c)){
                surveyMap.get(survey.Section__c).add(wrap);
            }else{
                surveyMap.put(survey.Section__c, new  List <surveywrapper> { wrap });
            }

        }

        return surveyMap;
    }

Wrapper class in apex:

public class surveywrapper{

        @AuraEnabled public string question{get;set;}
        @AuraEnabled public string questionId{get;set;}
        @AuraEnabled public List<String> optionList{get;set;}
        @AuraEnabled public List<StringWrapper> finaloptionList{get;set;}
        public surveywrapper(){
            mandatory = false;
            selected = false;
            optionList = new List<String>();
            finaloptionList = new List<StringWrapper>();
        }
    }
public class StringWrapper{
        public String option;
    }

Controller of the first lightning component:

action.setCallback(this, function(response) {
                if (response.getState() === "SUCCESS" && component.isValid()) {
                    console.log('response.'+response.getReturnValue());
                    var result = response.getReturnValue();
                    var arrayMapKeys = [];
                    var returnVal = [];
                    for(var key in result){
                        returnVal = result[key];
                        var finalresult = [];
                        var finalList = [];
                        for(var i=0; i<returnVal.length; i++){
                            var options = returnVal[i].optionList;
                            var finaloptions = [];
                            for(var j=0; j<options.length; j++){
                                finaloptions.push({'label':options[j],'value':options[j]});
                                returnVal[i].finaloptionList.push(finaloptions);
                            }

                        }
                        finalresult = returnVal;
                        arrayMapKeys.push({key: key, value: finalresult});
                    }
                    component.set("v.questions", arrayMapKeys);
                }
            });

Response in console:

Section_Name: Array(4)
0: {finaloptionList: Array(2), optionList: Array(2), question: "Question1" …}

I am now passing {!v.questions} to another component where I'm displaying the radio button

<aura:iteration items="{!v.questions}" var="mapKey" indexVar="key">
            <aura:iteration items="{!mapKey.value}" var="quest" >
                    <ui:outputText value="{!quest.question}" class="slds-text-heading_small"/>  

                    <lightning:radioGroup class="customRadioCls" aura:id="options"
                                      name="feedback"
                                      label=""
                                      options="{! quest.finaloptionList }"
                                      disabled="true"
                                      />
            </aura:iteration>
        </aura:iteration>

The final screen is shown as enter image description here

The options are coming blank. Where am I going wrong?

6
  • you setting arrayMapKeys to v.questions attribute , but you pushed list of objects in to arrayMapKeys object shape key value properties but in` aura:iteration` using finaloptionList it's not correct. better to create wrapper class with label and value properties then you can get and use list<wrapper class> directly in aura:iteration
    – sdandamud1
    Oct 15 '19 at 14:41
  • @sdandamud1 could you please elaborate?
    – User2529
    Oct 15 '19 at 14:43
  • can you post surveywrapper structure and can you post format of result in js controller?
    – sdandamud1
    Oct 15 '19 at 14:50
  • I've made changes to the question
    – User2529
    Oct 15 '19 at 15:01
  • your not setting any values for finaloptionList property of surveywrapper in Apex method, but in your Response in console: shows {finaloptionList: Array(2) so your Response in console: is customized response at before setting to` v.Question` i think. so what i understood is your trying to set the finaloptionList by using optionList with binding the label and value for each option then each option push in to finaloptionList is it right?
    – sdandamud1
    Oct 15 '19 at 15:22
0

lightning:radioGroup is itself a container to show the Radio Buttons using attribute for Options. In your code basically you are showing a list of "empty" radio groups by iterating through aura:iteration.

See the Salesforce example as below. You need to specify the options in an attribute.

<aura:component>
    <aura:attribute name="options" type="List" default="[
    {'label': 'apples', 'value': 'option1'},
    {'label': 'oranges', 'value': 'option2'}
    ]"/>
    <aura:attribute name="value" type="String" default="option1"/>
    <lightning:radioGroup
        aura:id="mygroup"
        name="radioButtonGroup"
        label="Radio Button Group"
        options="{! v.options }"
        value="{! v.value }"
        onchange="{! c.handleChange }"
        required="true" />
</aura:component>

You have to update your codes in similar lines

JS Controller

var finaloptions = [];
for(var j=0; j<options.length; j++){
    finaloptions.push({'label':options[j],'value':options[j]});
}
component.set("v.optionsList",values);

Component Markup

<aura:attribute name="optionsList" type="List" /> 
 ............
 ............
<lightning:radioGroup class="customRadioCls" aura:id="options"
        name="radioButtonGroup"
        label="Radio Button Group Title"
        options="{!v.optionsList}"
        value="{!v.value}" />
3
  • But what if I want to set the options dynamically? Also {! quest.finaloptionList } shows the following in the console : Array(2) 0: {label: "Strongly Disagree", value: "Strongly Disagree"} 1: {label: "Agree", value: "Agree"}
    – User2529
    Oct 15 '19 at 14:29
  • Yes, you can do it dynamically by updating the attribute with your JS array. I have update my answer, please check it.
    – Saroj Bera
    Oct 15 '19 at 14:37
  • The edit you’ve made above won’t work for me I guess. I'm displaying the options from a list of wrapper class. Kindly go through my apex controller.
    – User2529
    Oct 15 '19 at 14:42
0

i have done some Customization based on our conversation in comments area about your Question,i got following Apex Response in to JsController. let me know if any further customization needed.

    {  
   "section1":[  
      {  
         "finaloptionList":[  

         ],
         "optionList":[  
            "Strongly Disagree",
            "Agree"
         ]
      }
   ],
   "section2":[  
      {  
         "finaloptionList":[  

         ],
         "optionList":[  
            "Strongly Disagree",
            "Agree"
         ]
      }
   ],
   "section3":[  
      {  
         "finaloptionList":[  

         ],
         "optionList":[  
            "Strongly Disagree",
            "Agree"
         ]
      }
   ]
}

ApexController

@AuraEnabled
public static Map<String,List<surveywrapper>> Questions(String partnerName,List<String>selectedCommitteeList){
    Map<String,List<surveywrapper>> surveyMap = new Map<String,List<surveywrapper>>();
    List<String> sectionslist = new List<String>{'section1','section2','section3'};
    for(String str : sectionslist){
        surveywrapper wrap = new surveywrapper();


            wrap.optionList.add('Strongly Disagree');
            wrap.optionList.add('Agree');


        if(surveyMap.containsKey(str)){
            surveyMap.get(str).add(wrap);
        }else{
            surveyMap.put(str, new  List <surveywrapper> { wrap });
        }

    }

    return surveyMap;
}

cmpController

({
onInit: function (component) {
    var action = component.get("c.Questions");
   action.setCallback(this, function(response) {
            if (response.getState() === "SUCCESS" && component.isValid()) {                    
                var result = response.getReturnValue();
                var mapwrapper = []; 
                console.log('response.'+result);
                Object.keys(result).forEach(function(key) {
                    var sectionElement = {};
                    sectionElement.Id = key;
                    sectionElement.Value =[];
                    var surveywrapperObjectlist =result[key];
                    console.log(surveywrapperObjectlist);
                    surveywrapperObjectlist.forEach(function(SWobj){
                        var sectionRadioitem ={};
                        SWobj.optionList.forEach(optionitem =>{
                            sectionElement.Value.push({'label' : optionitem, 'value':optionitem });
                        });
                    });
                   mapwrapper.push(sectionElement);

                });
       console.log(mapwrapper);
       component.set("v.questions", mapwrapper);
            }
   });          


    $A.enqueueAction(action);
}
})

cmp

<aura:component controller="SeTesting" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,forceCommunity:availableForAllPageTypes" 
        access="global" >
<aura:attribute name="questions" type="List"/>

<aura:handler name="init" value="{!this}" action="{!c.onInit}"/>

<aura:iteration items="{!v.questions}" var="mapKey" indexVar="key">
    <lightning:card title="{!mapKey.Id}">

                <lightning:radioGroup class="customRadioCls" aura:id="options"
                                  name="feedback"
                                  label=""
                                  options="{! mapKey.Value }"
                                  disabled="true"/>
    </lightning:card>
    </aura:iteration>

enter image description here

1
  • Thank you for this. But I need to display the question attribute which is being populated in my apex controller and not the map's keys. Also, I have a couple more parameters in my wrapper class like 'selected' and 'mandatory' which are skipped in your answer. What should be done about those?
    – User2529
    Oct 16 '19 at 4:52
0

Okay I realized my mistake.

In my lightning controller:

for(var j=0; j<options.length; j++){
                                finaloptions.push({'label':options[j],'value':options[j]});
                                returnVal[i].finaloptionList.push(finaloptions);
                            }

The above code was inserting an array inside an array. I modified my code to

for(var j=0; j<options.length; j++){
                                    returnVal[i].finaloptionList.push({'label':options[j],'value':options[j]});
                                }

This fixed the issue

1
  • Glad you solved it. Don't forget to make your answer as the accepted solution.
    – Saroj Bera
    Oct 16 '19 at 5:28

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.