I found this example on a dynamic hierarchy for Accounts and I need help as to how to modify it to display an account hierarchy. I am unable to figure out why I recieve this error message when testing out my link and would like someone to inform me on what to add or change for my goal.
Error message:
Unable to serialize a map with a null key.
Apex Controller:
public class DynamicHierarchyController {
public String objectApiName {get;set;}
public String fieldApiName {get;set;}
public String nameField {get;set;}
public String currentsObjectId {get;set;}
public String topParentId {get;set;}
public String jsonMapsObjectString {get;set;}
private String jsonString;
Map<string, set<id>> sObjectIdMap = new Map<string, set<id>>();
Map<string, SObject> selectedsObjectMap = new Map<string, SObject>();
Map<id, sObject> allsObjectMap = new Map<id, sObject>();
public DynamicHierarchyController()
{
currentsObjectId = Apexpages.currentPage().getParameters().get('id');
}
public String getjsonMapString()
{
retrieveInfo();
return jsonString;
}
public void retrieveInfo()
{
String dynamicQuery = 'SELECT Id, ParentId, Parent_Account_for_LAM__c, Parent.Name, LAM_Shipping_Address__c, Name, Type, OPCO__c, LAM_Account_Owner__c, Rolling_12_Month_Total_Usage_kWh__c, Rolling_12_Month_Total_Revenue__c, Account_Status__c FROM Account LIMIT 50000';
// List <Account> dynamicQuery = [SELECT ID, ParentId, Parent_Account_for_LAM__c, Parent.Name, LAM_Shipping_Address__c, Name, Type, OPCO__c, LAM_Account_Owner__c, Rolling_12_Month_Total_Usage_kWh__c,
//Rolling_12_Month_Total_Revenue__c, Account_Status__c FROM Account ORDER BY ParentId LIMIT 50000];
for(sObject obj: Database.query(dynamicQuery))
{
allsObjectMap.put(obj.id,obj);
}
if(currentsObjectId != null)
{
List<SObject> objList = new List<SObject>();
String dQuery = 'SELECT ID FROM ' + objectApiName + ' WHERE id =\'' + currentsObjectId +'\'';
objList = Database.query(dQuery);
currentsObjectId = objList[0].Id;
retrieveTopParent(currentsObjectId);
retrieveAllChildRecords(new set<id>{topParentId});
system.debug(sObjectIdMap.keySet());
for(String str : sObjectIdMap.keySet())
{
selectedsObjectMap.put(str,allsObjectMap.get(str));
}
jsonString = JSON.serialize(sObjectIdMap);
jsonMapsObjectString = JSON.serialize(selectedsObjectMap);
}
}
public void retrieveTopParent(String sObjectId)
{
if(allsObjectMap.keySet().contains(sObjectId) && allsObjectMap.get(sObjectId).get(fieldApiName) != null)
{
topParentId = String.valueOf(allsObjectMap.get(sObjectId).get(fieldApiName));
retrieveTopParent(topParentId);
}
}
public void retrieveAllChildRecords(Set<id> sObjectIdSet)
{
if(sObjectIdSet.size() > 0)
{
Set<id> allChildsIdSet = new Set<id>();
for(String str : sObjectIdSet)
{
Set<id> childsObjectIdSet = new Set<id>();
for(sObject obj : allsObjectMap.values())
{
if(obj.get(fieldApiName) != null && String.valueOf(obj.get(fieldApiName)) == str)
{
childsObjectIdSet.add(obj.Id);
allChildsIdSet.add(obj.Id);
}
}
sObjectIdMap.put(str,childsObjectIdSet);
}
retrieveAllChildRecords(allChildsIdSet);
}
}
}
Visualfor Component:
<apex:component controller="DynamicHierarchyController" >
<apex:attribute name="objectName" description="Name of Object." type="String" required="true" assignTo="{!objectApiName}"/>
<apex:attribute name="FieldName" description="Name of the field of the object." type="String" required="true" assignTo="{!fieldApiName}"/>
<apex:attribute name="RepersenterField" description="Name field of the object." type="String" required="true" assignTo="{!nameField}"/>
<script src="https://code.jquery.com/jquery-1.12.4.min.js"></script>
<div id="parentDiv"></div>
<style>
#parentDiv ul:first-child
{
padding: 0;
}
#parentDiv li
{
list-style: none;
padding: 10px 5px 0 5px;
position: relative;
}
#parentDiv li span
{
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
/*border: 1px solid #999;*/
border-radius: 5px;
display: inline-block;
padding: 3px 8px;
cursor: pointer;
}
.selectedRecord
{
font-weight:bold;
color:blue;
}
</style>
<script>
var accountMap = JSON.parse('{!jsonMapString}');
var accountValueMap = JSON.parse('{!jsonMapsobjectString}');
var cClass = '';
if("{!topParentId}".indexOf('{!$CurrentPage.parameters.id}') != -1)
cClass = 'selectedRecord';
var ul = '<ul><li id="{!topParentId}" ><span class="' + cClass + '" onclick="toggleChilds(\'' + '{!topParentId}' + '\',event)" ><b id="i{!topParentId}" class="minus" style="font-size: 1.5em;" >-</b> ' + accountValueMap['{!topParentId}'].{!RepersenterField} + '</span></li></ul>' ;
$(ul).appendTo("#parentDiv");
appendUl('{!topParentId}','{!topParentId}');
function appendUl(key)
{
$.each( accountMap[key], function( index, value )
{
var dclass = '';
if(value.indexOf('{!$CurrentPage.parameters.id}') != -1)
dclass = 'selectedRecord';
var ul = '<ul class="' + key + '"><li id="' + value + '" ><span class="' + dclass + '" onclick="toggleChilds(\'' + value + '\',event)" ><b id="i' + value + '" class="minus" style="font-size: 1.5em;" >-</b> ' + accountValueMap[value].{!RepersenterField} + "</span></li></ul>" ;
$(ul).appendTo("#" + key);
if(value)
appendUl(value);
});
}
function toggleChilds(key,event)
{
$('.'+key).toggle('slow');
$('#i'+key).toggleClass('minus');
$('#i'+key).toggleClass('plus');
if($('#i'+key).hasClass("minus"))
$('#i'+key).html("-");
if($('#i'+key).hasClass("plus"))
$('#i'+key).html("+");
event.stopPropagation();
}
</script>
</apex:component>
Visualforce Page:
<apex:page standardcontroller="Account" showHeader="true" sidebar="true" >
<apex:pageblock title="Hierarchy">
<c:DynamicHierarchyComp objectName="Account" FieldName="ParentId" RepersenterField="Name"/>
</apex:pageblock>
</apex:page>