Friday, December 23, 2022

Wrapper Class In Salesforce Lightning Component

Wrapper Class in Salesforce 

In the previous Episode we discussed how to lightning component communicates with a server-side controller in brief.
In this episode, we are going to discuss what exactly wrapper class means, how it can help us to collect multiple data at once.

What is Wrapper Class ?

Consider an example of Gems where you always get different colors of gem packed in a single packet.
So when you unwrap that pack it's your choice to have a gem of the specific color or you can also have a combination of different colors.
It's absolutely your choice !!

But when you have a pack its collection of all the gems then which color to have first or not that all is your choice.

What if I say, If you will get only a single color in a single pack. In that case, you need to purchase multiple gems pack Right ??

It's not worth it because :

1. When I want only 3 yellow, 3 blue, 3 pink, 3 green Gems Why I will purchase an individual pack of different colors of gems.
2. No need to spend extra money on individual colors.
3. No need to unwrap multiple wraps.

Now, Connect it with salesforce wrapper class

In Salesforce Lightning component whenever we want multiple filtered data from a separate object or from the same object in a single list we use wrapper class.

For example,
If I want records of Account object with all records, some filtered Accounts and Records from Contact Object, Then I have to make multiple server calls to fetch this data like :

1. One server call for fetching Account object records.
2. Second server call for fetching Account Filtered records.
3. Third server call for fetching Contact object records.

Instead, If I get these records from the server-side controller (Apex Class) in a single server call in a single list then I can use this list and these individual list 1,2,3 wherever needed Sounds Great !! right ?? 

Yes, Hence Wrapper will give all colors of gems list. Now it's your choice where you want to use it as an individual also and together as well.

Basic Wrapper Class Syntax In Salesforce Apex Class/Controller :
-------------------------------------------------
public class wrapperClassController {

 @AuraEnabled 
    public static wrapper method(){
    //Get Required Account And Contact List by SOQL STEP 2
        List<Account> getAccount = [Select Id, Name  FROM Account];
        List<Contact> getContact = [Select Id, Name FROM Contact];    
//Instance before adding a list STEP 3
        wrapper wrp = new wrapper();
        wrp.accList = new List<Account>(getAccount);
        wrp.conList = new List<Contact> (getContact);
        return wrp;
    }

//Main Wrapper Class STEP 1
    public class wrapper{
       @AuraEnabled //Annotation when using for lightning component
          public List<Account> accList;
       @AuraEnabled 
          public List<Contact> conList;
    }   
}
-------------------------------------------------

In the above code 

STEP 1 : Create a wrapper class inside the main class:

First, create  public class wrapper{ } wrapper class and define what list you want like in my case I want account and contact list together hence I have created two lists accList and conList.

STEP 2 : Create method which returns the wrapper class :

Inside this method first, fetch all the list by SOQL query and store the result in the list.

STEP 3 : Add List into Wrapper Class :

Create an instance of wrapper class wrp and add a first account list getAccount as an input parameter. Same for second list getContact.

Now we have both list getAccount and getContact list stored inside single wrapper list.

Now it's time for hands-on with Lightning Component.

Let's have a look at today's recipe :
----------------------------------------------
wrapper class in salesforce
wrapper class in salesforce

----------------------------------------------

You can see there are multiple lists at once but in a single server call with the help of wrapper class, we have Hotel List, Guest List, Male Guest List, Female Guest List. 

Where I have used Male and Female Guest List in the single table as well as in the Common Guest table.

DATA MODEL :

Objects and Fields Used :

1. Hotel__c 
   - Name (Standard Field)
2. Guest__c
   - Name (Standard Field)
   - Gender__c (Picklist : Male, Female)

So let's jump on the Lightning component :

Server Side Controller wrapperClassController.apexc :
---------------------------------------------
public class wrapperClassController {
@AuraEnabled 
    public static wrapper method1(){
   //get records from database and store in list Step 2
        List<Hotel__c> getHotels = [Select Id, Name  FROM Hotel__c];
        List<Guest__c> guestList = [Select Id, Name FROM Guest__c];
        List<Guest__c> getMaleGuestList = [Select Id,Name, Gender__c FROM Guest__c WHERE Gender__c =: 'Male'];
        List<Guest__c> getFemaleGuestList = [Select Id,Name, Gender__c FROM Guest__c WHERE Gender__c =: 'Female'];
        
      //Create wrapper class instance and add list as a input              parameters  Step 3
        wrapper wrp = new wrapper();
        wrp.hotelList = new List<Hotel__c>(getHotels);
        wrp.guestList = new List<Guest__c>(guestList);
        wrp.maleGuestList = new List<Guest__c>(getMaleGuestList);
        wrp.femaleGuestList = new List<Guest__c>(getFemaleGuestList);
        return wrp;
    }
//Wrapper Class Step 1
    public class wrapper{
        @AuraEnabled public List<Hotel__c> hotelList;
        @AuraEnabled public List<Guest__c> guestList;
        @AuraEnabled public List<Guest__c> maleGuestList;
        @AuraEnabled public List<Guest__c> femaleGuestList;
    }  
}
---------------------------------------------

So simple to the first example I have created here 4 list, 
hotelList for displaying hotel object records.
guestList for displaying second object guest__c all records.
maleGuestList for displaying filtered male record from guest__c object.
femaleGuestList for displaying filtered female record from guest__c object.

and then by SOQL query we added result into its individual list first.
Then we created an instance of wrapper class and added hotel list to getHotels as a parameter to wrp.hotelList. Similarly for others.


Main Component WrapperLC.cmp :
---------------------------------------------
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes
                access="global
                controller="wrapperClassController">
//Attribute list we are using to display the lists
   <aura:attribute name="HotelList" type="List"/>
   <aura:attribute name="guestList" type="List"/>
   <aura:attribute name="maleList" type="List"/>
   <aura:attribute name="femaleList" type="List"/> 

//doInIt Handler To call the c.doInIt action when screen load
   <aura:handler name="init" value="{!this}" action="{!c.doInIt}"/>
  
  <p align="center" class="slds-text-heading_large ">Hotel List</p>
    <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_striped">
     <thead>
       <tr class="slds-line-height_reset">
        <th class="" scope="col">
       <div class="slds-truncate" >
        Hotel Name
        </div>
         </th> 
         </tr>
        </thead>
        <tbody>
         <tr class="slds-hint-parent">
         <th data-label="" scope="row">
          <div class="slds-truncate" >
           //Iterartion to load Hotel List
           <aura:iteration items="{!v.HotelList}" var="hotel">
            <p>{!hotel.Name}</p><br/>
            </aura:iteration>
             </div>
              </th>
              </tr>
        </tbody>
    </table>
     <p align="center" class="slds-text-heading_large ">
       Guest List
     </p>
    <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_striped">
        <thead>
        <tr class="slds-line-height_reset">
       <th class="" scope="col">
    <div class="slds-truncate" >
     Guest Name
     </div>
    </th> 
     <th class="" scope="col">
   <div class="slds-truncate" >
       Male Guest Name
   </div>
    </th> 
     <th class="" scope="col">
    <div class="slds-truncate" >
            Female Guest Name
     </div>
      </th> 
       </tr>
        </thead>
        <tbody>
         <tr class="slds-hint-parent">
            <th data-label="" scope="row">
         <div class="slds-truncate" >
        //Iterartion to load Guest List In A Guest table
       <aura:iteration items="{!v.guestList}" var="guest">
          <p>{!guest.Name}</p><br/>
        </aura:iteration>
          </div>
           </th>
           <th  scope="row">
         <div class="slds-truncate" >
        //Iterartion to load Male Guest List In A Guest table
        <aura:iteration items="{!v.maleList}" var="male">
          <p>{!male.Name}</p><br/>
        </aura:iteration>
        </div>
         </th>
        <th  scope="row">
       <div class="slds-truncate" >
       //Iterartion to load Female Guest List In A Guest table
       <aura:iteration items="{!v.femaleList}" var="female">
         <p>{!female.Name}</p><br/>
         </aura:iteration>
          </div>
          </th>
         </tr>
        </tbody>
    </table>
     <p align="center" class="slds-text-heading_large ">
       Male Guests
     </p>
    <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_striped">
        <thead>
      <tr class="slds-line-height_reset">
       <th class="" scope="col">
       <div class="slds-truncate" >
         Male Guest Name
       </div>
        </th> 
        </tr>
        </thead>
        <tbody>
        <tr class="slds-hint-parent">
         <th data-label="" scope="row">
         <div class="slds-truncate" >
      //Iterartion to load Male Guest List In Male Guest table
      <aura:iteration items="{!v.maleList}" var="male">
       <p>{!male.Name}</p><br/>
        </aura:iteration>
           </div>
           </th>
          </tr>
        </tbody>
    </table>
      <p align="center" class="slds-text-heading_large ">
       Female Guests
      </p>
    <table class="slds-table slds-table_cell-buffer slds-table_bordered slds-table_striped">
        <thead>
        <tr class="slds-line-height_reset">
                <th class="" scope="col">
        <div class="slds-truncate" title="">
             Female Guest Name
          </div>
        </th> 
        </tr>
        </thead>
        <tbody>
            <tr class="slds-hint-parent">
                <th data-label="" scope="row">
                 <div class="slds-truncate" >
      //Iterartion to load Male Guest List In Male Guest table
        <aura:iteration items="{!v.femaleList}" var="female">
         <p>{!female.Name}</p><br/>
          </aura:iteration>
          </div>
          </th>
         </tr>
        </tbody>
    </table>
    <br/>
    <br/>
</aura:component>
---------------------------------------------

In component file we added apex class name as a controller="wrapperClassController" then I have used aura:iteration to iterate the list received from the controller. For the design, I have used salesforce data table from design library.

also aura:handler to call doInIt method when my application/ Component loads.

JS Controller WrapperLC.js :
---------------------------------------------
({
     doInIt : function(component, event, helper) {
var action = component.get("c.method1");
       
        action.setCallback(this, function(response){
            var state = response.getState();
            if(state === "SUCCESS")
            {
     var response = response.getReturnValue();
     component.set("v.HotelList", response.hotelList); 
     component.set("v.guestList", response.guestList); 
     component.set("v.maleList", response.maleGuestList);  
     component.set("v.femaleList", response.femaleGuestList);  
            }
            else if(state === "INCOMPLETE")
            {
                //do something 
            }
            else if(state === "ERROR")
            {
             var error = response.getError();
             if(error)
             {
                 console.log("error"+errors);
             }
            }
        });
          $A.enqueueAction(action);
}
})
---------------------------------------------

Js Controller or Client-side controller will call c.method1 from the server-side controller. and we just set the list from a response of server call to different lists
Like this :
     component.set("v.HotelList", response.hotelList); 
     component.set("v.guestList", response.guestList); 
     component.set("v.maleList", response.maleGuestList);  
     component.set("v.femaleList", response.femaleGuestList);

And finally we need to add this component in Lightning Application to view the output of this component.

Lightning Application WrapperLCApp.app :
---------------------------------------------

<aura:application extends="force:slds">

    <c:WrapperLC/>

</aura:application>
---------------------------------------------

Click On the Preview Button. 

Output :
---------------------------------------------
wrapper class in salesforce
wrapper class in salesforce


No comments:

Post a Comment

Understanding Wire vs Imperative Apex Method Calls in Salesforce Lightning Web Components (LWC)

Understanding Wire vs Imperative Apex Method Calls in Salesforce Lightning Web Components (LWC) Introduction: Salesforce Lightning Web ...