Hello, I would like to create a lightning datatable (or any another other type of lightning tables that would work) in my aura component in order to display a nested data in a form of a tree structure.
The data is composed of accounts with their related contacts. I built it using a wrapper class in the apex controller and then I pass it to the component through a helper in order to display it.
I tested the accessibility of that data in my component ( i managed to display it as simple text) but after trying to organize it in a datatable, this later is not displaying any of my data.
My question is how can I define the attribute column of the datatable so it allows me to show the accounts with their related contacts?
Here is what I made.
Apex controller
public with sharing class ReferralProgramApexController {
@AuraEnabled
public static List<AccountRelatedContactsWrapper> getNestedAccounts() {
//create a list to store in it the custom objects of type AccountRelatedContactsWrapper
List<AccountRelatedContactsWrapper> AccountsContactsWrapperList = new List<AccountRelatedContactsWrapper>();
//retreive 3 accounts each with all its related contacts
List<Account> AccountsContactsNestedList = [SELECT Id, Name,
(SELECT Id, Email, phone From Contacts)
FROM Account Limit 3];
//check if the accounts list is not empty
if(!AccountsContactsNestedList.isEmpty()){
//loop over the retrieved accounts
for(Account acc : AccountsContactsNestedList){
//create a wrapper object of type AccountRelatedContactsWrapperand add it to the objects list
AccountsContactsWrapperList.add(new AccountRelatedContactsWrapper(acc, acc.Contacts));
}
}
return AccountsContactsWrapperList;
}
// wrapper class with @AuraEnabled and {get;set;} properties
public class AccountRelatedContactsWrapper{
//properties
@AuraEnabled
public Account accRecord{get;set;}
@AuraEnabled
public List<Contact> contactList{get;set;}
//constructor
public AccountRelatedContactsWrapper(Account accRecord,List<Contact> contactList){
this.accRecord = accRecord;
this.contactList = contactList;
}
}
}
helper
({
getData : function(component) {
// Create a remote method call (Action) from apex controller
let action = component.get("c.getNestedAccounts");
// Add callback behavior for when response is received
action.setCallback(this, function(response) {
let state = response.getState();
if (state === "SUCCESS") {
//set the component accountlList attribute with fetched data
component.set("v.AccountNestedList", response.getReturnValue());
}
else {
console.log("Failed with state: " + state);
}
});
// Send action off to be executed
$A.enqueueAction(action);
}
})
controller
({
// Load Accounts from Salesforce
FetchData: function(component, event, helper) {
//**********set the datatable according to the data to be fetched
component.set('v.columns', [
{label: 'Account Id', fieldName: 'accRecord.Id', type: 'text' },
{label: 'Name', fieldName: 'accRecord.Name', type: 'text' },
{label: 'Email', fieldName: 'contactList.Email', type: 'text' },
{label: 'Phone', fieldName: 'contactList.Phone', type: 'text' }
]);
helper.getData(component);
}
})
component
<aura:component controller = "ReferralProgramApexController"
implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
<aura:attribute name="AccountNestedList" type="object[]"/>
<aura:attribute name="columns" type="List"/>
<aura:handler name="init" action="{!c.FetchData}" value="{!this}"/>
<aura:if isTrue="{!not(empty(v.AccountNestedList))}">
<lightning:datatable data="{!v.AccountNestedList.accRecord}"
columns="{!v.columns}"
keyField="Id"
hideCheckboxColumn="true"/>
<!-- <aura:iteration items="{!v.AccountNestedList}" var="obj" indexVar="sNo">
{!obj.accRecord.Name}
<aura:iteration items="{!obj.contactList}" var="cont">
{!cont.Email} {!cont.Phone}
</aura:iteration>
</aura:iteration>
-->
<aura:set attribute="else">
<div Style="text-align : center"> " There are no contacts " </div>
</aura:set>
</aura:if>
</aura:component>
my data I got from a list of wrapper objects
Thank you in advance.
Hi YARA ,
Apex controller
public with sharing class ReferralProgramApexController {
@AuraEnabled
public static List<Map<String,Object>> getNestedAccounts() {
List<Map<String,Object>> myDataList = new List<Map<String,Object>>();
List<Account> AccountsContactsNestedList = [SELECT Id, Name,
(SELECT Id, Email, phone From Contacts)
FROM Account Limit 3];
for (Account myObj : AccountsContactsNestedList) {
Integer i = 0;
for (Contact con : myObj.Contacts){
if ( i == 0) {
Map<String, Object> myMap = new Map<String, Object>();
myMap.put('accRecord.Id',myObj.Id);
myMap.put('accRecord.Name',myObj.Name);
myMap.put('contactList.Email',con.Email);
myMap.put('contactList.Phone',con.Phone);
myDataList.add(myMap);
} else {
Map<String, Object> myMap = new Map<String, Object>();
myMap.put('accRecord.Id',null);
myMap.put('accRecord.Name',null);
myMap.put('contactList.Email',con.Email);
myMap.put('contactList.Phone',con.Phone);
myDataList.add(myMap);
}
i = i + 1;
}
}
return myDataList;
}
}
<aura:component controller = "ReferralProgramApexController"
implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >
<aura:attribute name="AccountNestedList" type="object[]"/>
<aura:attribute name="columns" type="List"/>
<aura:handler name="init" action="{!c.FetchData}" value="{!this}"/>
<aura:if isTrue="{!not(empty(v.AccountNestedList))}">
<lightning:datatable data="{!v.AccountNestedList}"
columns="{!v.columns}"
keyField="Id"
hideCheckboxColumn="true"/>
<!-- <aura:iteration items="{!v.AccountNestedList}" var="obj" indexVar="sNo">
{!obj.accRecord.Name}
<aura:iteration items="{!obj.contactList}" var="cont">
{!cont.Email} {!cont.Phone}
</aura:iteration>
</aura:iteration>
-->
<aura:set attribute="else">
<div Style="text-align : center"> " There are no contacts " </div>
</aura:set>
</aura:if>
</aura:component>
The controller and helper are unchanged.