Triggers and Helper Class
Triggers are used to capture events on any DML operation and perform custom logic implementation on that event. The Salesforce’s best coding practices suggest that we should have only one Trigger on an object and a Helper class for handling the events of trigger and methods to perform the required custom implementation. So in this article, I’ll explain how to work with the Triggers and Helper Class and use the optimal way to code and use the best coding practices.
First of all, we create only one trigger for an object and use the trigger context variables to differentiate the DML events.
trigger HelloWorldTrigger on Account (before insert, before update, before delete, after insert, after update, after delete, after undelete) {// Your code here}
Trigger events can be a comma-separated list of one or more of the following events as described in code.
- before insert
- before update
- before delete
- after insert
- after update
- after delete
- after undelete
Just to give an idea to newcomers, here is the list of Trigger Context Variables:
- Trigger.new
- Trigger.newMap
- Trigger.old
- Trigger.oldMap
- Trigger.isInsert
- Trigger.isUpdate
- Trigger.isDelete
- Trigger.isUndelete
- Trigger.isBefore
- Trigger.isAfter
That’s all the Trigger context variables that you’ll be using in general tasks.
We capture and differentiate all the trigger events with the help of the Switch and Trigger.operationType context variable.
trigger AccountTrigger on Account (before insert, before update, before delete, after insert, after update, after delete, after undelete) {
AccountTriggerHandler handler = new AccountTriggerHandler(trigger.newMap, trigger.oldMap);
//Get the trigger toggle
List<Trigger_Setting__mdt> triggerSettingList = [SELECT Id, isEnabled__c FROM Trigger_Setting__mdt WHERE MasterLabel = 'AccountTriggerHandler' LIMIT 1];
if (!triggerSettingList.isEmpty() && triggerSettingList[0].isEnabled__c){
switch on Trigger.OperationType {
when BEFORE_INSERT {
handler.handleBeforeInsert();
}
when BEFORE_UPDATE {
handler.handleBeforeUpdate();
}
when BEFORE_DELETE {
handler.handleBeforeDelete();
}
when AFTER_INSERT {
handler.handleAfterInsert();
}
when AFTER_UPDATE {
handler.handleAfterUpdate();
}
when AFTER_DELETE {
handler.handleAfterDelete();
}
when AFTER_UNDELETE {
handler.handleAfterUnDelete();
}
when else {
}
}
}
}In those event capturing conditions we call methods of Helper class. Now we will shift over to Helper Class. The concept behind having a helper class is to have all the logic outside trigger for reusability and I use it to basically cover the code easily with Test class. As it’s easy to find a test class for a class then a test class for the trigger. Moreover, we can even create sub-methods for writing logic which can be used by other methods in the class.
Another interesting thing you will find on the above code is Trigger_Setting__mdt. Which is one generic custom meta-data type act as a toggle for each and every trigger. If you don't want to fire specific trigger during any DML operation on object then just uncheck isEnabled__c field on that trigger’s custom meta-data record and logic related to that trigger will not execute.
public with sharing class AccountTriggerHandler {
private map<Id, Account> newMap;
private map<Id, Account> oldMap;
public AccountTriggerHandler(map<Id, Account> mapNewAccount, map<Id, Account> mapOldAccount) {
newMap = mapNewAccount;
oldMap = mapOldAccount;
}
public void handleBeforeUpdate(){
checkAccountUpdates();
}
private void checkAccountUpdates() {
for (Id key : newMap.keySet()) {
Account currentAccount = newMap.get(key);
Account oldAccount = oldMap.get(key);
//Your logic here
}
}
}We are capturing the context of the account before and after any DML operation through trigger.newMap and trigger.oldMap. It's good to use map rather than a list to capture the context of object.
Fun part:
Question for the ones who have a piece of good knowledge of Salesforce. Can we use Trigger Context variables in an apex class? If yes then how? If no then why? Do think twice before you answer.
