Thursday, 12 June 2014

Fun with maps in apex-Part 2

This is an extension of my previous blog on Fun with Maps .So from years of coding now on apex we realize we do lot of repetitive  coding ,The code statements keep repeating but objects ,fields and org keep changing .

So here my problem statement was ,I was using the logic of forming a Map of ParentId and List of Child Records frequently for different triggers and different visualforce classes .Something like below as mentioned in the previous blog.

Here is the sample code that kept on repeating for me
Map < Id, List < Contact >> mapAccIdByCntlst = new Map < Id, List < Contact >> ();
for (Contact c: [Select Id, name, AccountId from Contact where AccountId != null]) {
// AccountId mapping with Contact List
if (mapAccIdByCntlst.containsKey(c.AccountId)) {
mapAccIdByCntlst.get(c.AccountId).add(c); //tricky part .Here map.get(key) is returning list and we are adding contacts to the list
} else {
List < Contact > lstcnts = new List < Contact > (); //Initialize list as no key is found before and first time we get key
lstcnts.add(c);
mapAccIdByCntlst.put(c.AccountId, lstcnts);
}
}
view raw Maputil hosted with ❤ by GitHub

The Object kept on changing for various triggers and classes in my org but the basic logic remained same of forming a collection of Map<Id,List<Sobject>>

Repeating code is never a good pattern and felt need to write an utility that can take care of this .Here is my utility class that can be used ti generalize the concept of collecting parentId and the list of child records (List<childrecord>)

public class ParentChildMapHelper{
public static Map<String,List<sobject>> buildGeneralisedMap(String fieldname,List<Sobject> lstsobject){
Map<String,List<sobject>> mapIdbySobject=new Map<String,List<sobject>>();
for(Sobject s:lstsobject){
if (mapIdbySobject.containsKey((String)s.get(fieldname))){
mapIdbySobject.get((String)s.get(fieldname)).add(s); //tricky part .Here map.get(key) is returning list and we are adding contacts to the list
} else{
List <sobject> lstsobjects = new List <sobject> (); //Initialize list as no key is found before and first time we get key
lstsobjects.add(s);
mapIdbySobject.put((String)s.get(fieldname), lstsobjects);
}
}
return mapIdbySobject;
}
}
The advantage of this pattern is we dont have to code this logic again and again .It accepts the string of the ParentId Field and also List<sobject> .

Lets see simple use cases of this Utility

1)Usage in Trigger
trigger ContactTrigger on Contact (after delete, after insert, after undelete,
after update, before delete, before insert, before update) {
if(trigger.isAfter && trigger.isInsert){
Map<String,List<Contact>> mapIdByList=ParentChildMapHelper.buildGeneralisedMap('AccountId',trigger.new);
system.debug(mapIdByList);
}
}
view raw triggerSample hosted with ❤ by GitHub
2)Usage to typecast this class into necessary map
Map<String,List<Contact>> mapIdByList=(Map<String,List<Contact>>)ParentChildMapHelper.buildGeneralisedMap('AccountId',lstsobject);
system.debug('My new Map '+mapIdByList);
view raw TypecastingMap hosted with ❤ by GitHub


Following illustrates how easy it is to generalize this concept and just write once and avoid repetitive usage on all objects .

Thanks and hopefully you enjoyed this post .Looking forward for your comments and feedback .

Introducing Lightning Base Components

Lightning Base Components are great addition to the platform and in fact revolutionary .One of the concerns around lightning component ...