Thursday, 6 February 2020

Use Maps in Lightning Components

Most probably in Lightning Components, we only deal with Lists to retrieve data from Apex Controller. But there are many scenarios Lists are not enough to retrieve data. So, Maps are very convenient in any simple or complex scenarios. There are very less resources available on it.

So, consider an example of two object (Objects – Consumer & Product) with junction object (Consumer Product).

Relationship as below.

Consumer has Master Details to Consumer Product.
Product has Lookup to Consumer Product.

Scenario to be implement: I want to show record of Products which are associated with Consumers in tab view filtered by Product Family.


Explanation :

Below I have provided Lightning Component bundle and Apex Class.


  • Take return type of apex method as map<String,List<Consumer_Products__c>>
  • By using force:hasRecordId, I get current Consumer record Id, will query on Consumer Product to get details of Product related to Consumer.
  • Then iterate above query and put all data in 
Map<String,List<Consumer_Products__c>> CustToProd = new Map<String,List<Consumer_Products__c>>(); 

  •  In JS Controller,
 var custs = []; 
 var conts = response.getReturnValue(); 
 for(var key in conts){ 
 custs.push({value:conts[key], key:key}); //Here we are creating the list to show on UI. 
 } 
  component.set("v.FamilyMap ",custs);

  • Use FamilyMap in lightning component to iterate and show required data.
  • First iteration - To iterate over Keys from Map.
<aura:iteration items="{!v.FamilyMap}" var="FirstIteration" indexVar="key">

  • Second Iteration  - To iterate over Product List.
<aura:iteration items="{!FirstIteration.value}" var="SecondIteration" indexVar="key1">

  • Fetch the Product date by using Var - 'SecondIteration' .
{!SecondIteration.Product__r.Name}




Lightning Component - 
<aura:component controller="ConsumerProdDetails" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <aura:attribute name="CustProductDetails" type="Object" />
    <aura:handler name="init" value="{!this}" action="{!c.doinit}" />
    <aura:attribute name="FamilyMap" type="Map" />
 
    <div>
        <div class="slds-page-header">
            <h2>
                <lightning:icon class="myUniqueClass" iconName="standard:event" alternativeText="Event" />
                <span class="boldtext" title="Product 360 View">
                    <b>Product 360 View</b>
                </span>
            </h2>
        </div>
     
        <lightning:tabset  variant="default" >
            <aura:iteration items="{!v.FamilyMap}" var="FirstIteration" indexVar="key">
                <lightning:tab  label="{!FirstIteration.key}"  > 

                    <table class="slds-table slds-table--bordered slds-table--fixed-layout  slds-max-medium-table--stacked-horizontal">
                        <thead>
                            <tr class="slds-line-height_reset">
                                <th class="" scope="col">
                                    <div class="slds-truncate" title="AccountId">Account Id</div>
                                </th>
                                <th class="" scope="col">
                                    <div class="slds-truncate" title="Product Name">Product Name</div>
                                </th>
                             
                            </tr>
                        </thead>
                        <tbody>
                            <aura:iteration items="{!FirstIteration.value}" var="SecondIteration" indexVar="key1">
                                <tr class="slds-hint-parent slds-cell-wrap">
                                    <th data-label="AccountId" scope="row">
                                        <div class="slds-truncate" >
                                            <!--onclick="{!c.StmtData}"-->
                                            <a href="#" tabindex="-1">{!SecondIteration.Id}</a>
                                        </div>
                                    </th>
                                    <td data-label="Product Name">
                                        <div class="slds-truncate" ><ui:outputText aura:id="ProdName" value="{!SecondIteration.Product__r.Name}"/></div>
                                    </td>
                                </tr>
                            </aura:iteration>
                        </tbody>
                    </table>
                </lightning:tab>
            </aura:iteration>
        </lightning:tabset>
     
    </div>
</aura:component>
JS Controller :

({
doinit : function(component, event, helper) {
        var rid = component.get("v.recordId");
        var action = component.get('c.returnConsDetail');
        action.setParams({Key : rid});
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
     
                var custs = [];
                var conts = response.getReturnValue();
                for(var key in conts){
                    custs.push({value:conts[key], key:key}); //Here we are creating the list to show on UI.
                }
                component.set("v.FamilyMap ",custs);
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " +
                                    errors[0].message);
                    }
                }
                else {
                    console.log("Unknown Error");
                }
            }
        });
        $A.enqueueAction(action);
}
})

Apex Controller :
@auraEnabled
    public static map<String,List<Consumer_Products__c>> returnConsDetail(String Key){
        Set<id> prodId = new Set<id>();
        Map<String,List<Product2>> FamToProd = new Map<String,List<Product2>>();
        Map<String,List<Consumer_Products__c>> CustToProd = new Map<String,List<Consumer_Products__c>>();
        List<Consumer_Products__c> listCustAccs = [Select Id, Product__r.Name, Product__r.Family from Consumer_Products__c where Consumer__c =:key ];
        for(Consumer_Products__c ca : listCustAccs){
            prodId.add(ca.Product__c);
        }
        for(Consumer_Products__c CA : listCustAccs){
            if(CustToProd.containskey(CA.Product__r.family)){
                CustToProd.get(CA.Product__r.family).add(CA);
            }else{
                List<Consumer_Products__c> chlist = new List<Consumer_Products__c>();
                chlist.add(CA);
                CustToProd.put(CA.Product__r.family,chlist); 
            }
        }
        return CustToProd;
    }
Now Add component to Consumer record page by Using App Builder.

No comments:

Post a Comment