3

I'm working a lightning component, which has a requirement of displaying a dynamic table.

For that, I need to iterate over a map (Map>) and display the values.

So, How can I retrieve map from apex controller and display values/key on the component ?

Apex Controller method signature –

public static Map<Id, Map<String, String>> getDataCollectionTableValues(Id dataCollectionId){

Apex method return value –

{  
   a0E0k000003aEKUEA2=   {  
      Field_10__c=test1,
      Field_1__c=test2,
      Field_2__c=test3,
      Field_3__c=test6,
      Field_4__c=null,
      Field_5__c=null,
      Field_6__c=test7,
      Field_7__c=null,
      Field_8__c=null,
      Field_9__c=test,
      ...
   }
}

Lightning helper – I’ve passed id parameter to controller method and set response to the map attribute.

({
    loadDataCollection: function(component) {

        var action = component.get("c.getDataCollectionTableValues");
        action.setParams({
            dataCollectionId : component.get("v.recordId")
        });

        action.setCallback(this, function(response)
        {
            var state = response.getState();
            if (state === "SUCCESS")
            {
                component.set("v.dataCollectionRecords", response.getReturnValue());
                 console.debug(response.getReturnValue());
            }else
            {
                console.debug(response.error[0].message);
            }
        });
        $A.enqueueAction(action);
    }
})

Component –

<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global" controller="DataCollectionTableController">
    <aura:attribute name="recordId" type="Id"/>
    <aura:attribute name="dataCollection" type="Data_Collection__c" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:attribute name="dataCollectionRecords" type="Map"/>
    <aura:iteration items="{!v.dataCollectionRecords}" var="dcrRecord" indexVar="key">
        {!key}
        {!dcrRecord.key}
    </aura:iteration>

</aura:component>
1
  • What does your lightning controller response return? Pleas include debugging info
    – glls
    Commented May 8, 2018 at 11:37

1 Answer 1

6

Well Aura:iteration does not support map. Thus you to write your own parser which will convert the Map into a list of custom javascript object that can be iterated by aura: iteration.

Assuming this is the response from the Apex controller.

{  
   a0E0k000003aEKUEA2=   {  
      Field_10__c=test1,
      Field_1__c=test2,
      Field_2__c=test3,
      Field_3__c=test6,
      Field_4__c=null,
      Field_5__c=null,
      Field_6__c=test7,
      Field_7__c=null,
      Field_8__c=null,
      Field_9__c=test,
      ...
   }

}

We will iterate over Outer Map and then over Inner Map, this will allow us to create Javascript object which we will then pass to aura:iteration.

({
    loadDataCollection: function(component) {

        var action = component.get("c.getDataCollectionTableValues");
        action.setParams({
            dataCollectionId : component.get("v.recordId")
        });

        action.setCallback(this, function(response)
                           {
                               var state = response.getState();
                               if (state === "SUCCESS")
                               {
                                   var map = response.getReturnValue();
                                   var parsingWarpper=[];
                                   console.log(map);

                                   //Iterate over the key for Outer Map
                                   Object.keys(map).forEach(function(key) {

                                       var individualElement = {};
                                       individualElement.Id = key;
                                       individualElement.Value =[];
                                       var innerMapObject =map[key];

                                       console.log(innerMapObject);
                                       //Iterate over the key for Inner  Map
                                       Object.keys(innerMapObject).forEach(function(key2) {
                                           console.log(key2);
                                           var innerIndivididualElement ={};
                                           innerIndivididualElement.Key = key2;
                                           innerIndivididualElement.Value = innerMapObject[key2];

                                           individualElement.Value.push(innerIndivididualElement);
                                       });  
                                       parsingWarpper.push(individualElement);


                                   });
                                   console.log(parsingWarpper);
                                   component.set("v.myMap",parsingWarpper);
                               }else
                               {
                                   console.debug(response.error[0].message);
                               }
                           });
        $A.enqueueAction(action);
    }
})

// Your component will be:

    <aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global" controller="DataCollectionTableController">
    <aura:attribute name="recordId" type="Id"/>
    <aura:attribute name="dataCollection" type="Data_Collection__c" />
    <aura:handler name="init" value="{!this}" action="{!c.doInit}" />
    <aura:attribute name="dataCollectionRecords" type="Map"/>
    <aura:attribute type="Object" name="myMap" ></aura:attribute>


    <aura:iteration items="{!v.myMap}" var="ele" indexVar="key">

        {!ele.Id} <br></br>
        <aura:iteration items="{!ele.Value}" var="ele2" indexVar="key2">
            {!ele2.Key} ---> {!ele2.Value} <br></br>

        </aura:iteration>
        <hr></hr>
    </aura:iteration>

</aura:component>

As its nested object, we have to iterate the inner iteration using aura:iteration again.

The resultant looks like what you want.

enter image description here

2
  • +1 for the answer. Avoid Object.keys(map).forEach() when the support for IE is still at large.. IE11 runs in Quirks Mode, and in this mode forEach() would throw an error. Instead, use the normal for loops using key indexes.
    – Sumuga
    Commented May 9, 2018 at 7:47
  • 1
    I have now seen companies are ditching IE as it's not worth developer's time and investors money to support outdated browsers. Commented May 9, 2018 at 15:01

You must log in to answer this question.

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