[SalesForce] Rendering data from Wrapper Class into Lightning Data table

Hi I'm trying to render data from a wrapper class it's coming up with row but values are empty.

Component:

<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId,force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,forceCommunity:availableForAllPageTypes"
                access="global"
                controller="CTASReferralController">

    <!-- Record Details -->
    <aura:attribute name="record" type="Object" description="The record object to be displayed"/>
    <aura:attribute name="simpleRecord" type="Object" description="A simplified view record object to be displayed"/>
    <aura:attribute name="recordError" type="String" description="An error message bound to force:recordData"/>

    <force:recordData aura:id="record"
                      layoutType="FULL"
                      recordId="{!v.recordId}"
                      targetError="{!v.recordError}"
                      targetRecord="{!v.record}"
                      targetFields="{!v.simpleRecord}"
                      mode="VIEW"/>


    <aura:attribute name="data" type="Object"/>
    <aura:attribute name="columns" type="List"/>
    <aura:attribute name="recordId" type="String"/>
    <!-- This attribute will hold the update records from data table-->
    <aura:attribute name="updatedRecord" type="Object[]" />

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

    <div class="Record Details">
        <lightning:card iconName="standard:account" title="{!v.simpleRecord.Name}" >
            <div class="slds-p-horizontal--small">
                <p class="slds-text-heading--small">
                    <lightning:formattedText title="page name" value="Refer Participants" /></p>
            </div>
        </lightning:card>   
    </div>
    <!-- You must define keyField as 'Id' to save the record back in Salesforce
'onsave' attribute will executed when user clicks on save button -->
    <lightning:card title=" ">
        <center>    
            <h1 class="slds-text-heading--medium">Participants to Refer</h1>
        </center>
        <br/>
        <lightning:datatable
                             aura:id="accountDataTable"
                             columns="{! v.columns }"
                             data="{! v.data }"
                             keyField="Id"
                             onsave ="{!c.onSave}"
                             hideCheckboxColumn="true"
                             onrowaction="{! c.handleRowAction }" />
    </lightning:card>
</aura:component>

Controller:

({
doInit : function(component, event, helper) {        
        component.set('v.columns', [
            {label: 'Full Name', fieldName: 'con.Name', type: 'url'},
            {label: 'Phone', fieldName: 'con.Phone', type: 'text'},
            {label: 'Mobile Phone', fieldName: 'con.MobilePhone', type: 'text'},
            {label: 'Mailing City', fieldName: 'con.MailingCity', type: 'text'},
            {label: 'Mailing Zip/Postal Code', fieldName: 'con.MailingPostalCode', type: 'text'},
            {label: 'Type', fieldName: 'ref.Type__c', type: 'text'},
            {label: 'Referral Date', fieldName: 'ref.Referral_Date__c', type: 'Date'},
            {label: 'Comments', fieldName: 'ref.Comments__c', type: 'text', editable:'true'}
        ]);        
        helper.getParticipants(component, helper);
    }
})

Helper:

({
    getParticipants : function(component, event, helper) {
        debugger;
        var action = component.get("c.getParticipantsToRefer");
        action.setParams({
            "accId": component.get("v.recordId")
        });
        action.setCallback(this,function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.data", response.getReturnValue());
                console.log(response.getReturnValue());
            }
        });
        $A.enqueueAction(action);
    }
})

Apex Controller:

public class CTASReferralController {

    @AuraEnabled
    public static List<ContactDecorator> parToRefer {get;set;}
    public static List<Contact> referredPar {get;set;}
    public static Id accountId;
    public static String status {get;set;}
    public static String postProcessing {get;set;}


    @AuraEnabled
    public static List<ContactDecorator> getParticipantsToRefer(Id accId){
        // initialise variables
        //status = '';
        //postProcessing = '';
        parToRefer = new List<ContactDecorator>();
        //referredPar = new List<Contact>();
        // Query all the contacts belonging to the account that have not been referred to CTAS yet.
        List<Contact> participantsToRefer = [SELECT Id, Name, Job_Title__c, Phone, MobilePhone, MailingPostalCode, Employment_Status__c, CTAS_Stage__c, 
                            MailingCity FROM Contact WHERE AccountId = :accId 
                            AND RecordTypeId = :RecordTypeUtil.getRecordTypeIdFor('Contact','Participant') AND CTAS_Stage__c = null];

        for(Contact con : participantsToRefer){
            if(con.CTAS_Stage__c == null){
                parToRefer.add(new ContactDecorator(con, new Referral__c(Participant_Name__c = con.Id, Type__c = ReferralUtil.REFERRAL_TYPE_CTAS, Referral_Date__c = Date.today(), comments__c = '')));
            }
        }

        System.debug('data fetched'+parToRefer);
        if(!parToRefer.isEmpty()) {
            return parToRefer;
        } 
        return null;
    }   
}
    //wrapper class
    public class ContactDecorator{


        @AuraEnabled public Boolean selected{get;set;}
        @AuraEnabled public Contact con{get;set;}
        @AuraEnabled public Referral__c ref{get;set;}

        public ContactDecorator(Contact con, Referral__c ref){
            this.selected = true;
            this.con = con;
            this.ref = ref;
        }
    }
}

enter image description here

Best Answer

The reason here is that lightning:datatable doesn't support complex objects. As columns in datatable you can only use speciffic fields of an object so you can't do something like

{label: 'Phone', fieldName: 'con.Phone', type: 'text'},

Instead you need to prepare your data so you don't need to reach fields of an object inside it:

{label: 'Phone', fieldName: 'contactPhone', type: 'text'},

This requires some work to be done on Apex side of your component - probably changing the definition of ContactDecorator.class so it lightning:datatable can have direct access to Contact's and Referral' fields.

Related Topic