Episode 5 – Demystifying Apex Triggers

In this episode we will learn about writing triggers to fire business logic using Apex. Join us as you embark on this wonderful journey to become a champion Salesforce developer.


  • Order of Execution
  • When & How Triggers are invoked
  • Trigger Events
  • Avoiding Recursive Trigger Calls
  • Q & A

Most importantly don’t break a leg if you are overwhelmed with the pace of the live sessions. All Apex Hours for Student sessions will be recorded and will be available on our YouTube channel.

Please register here and follow our ApexHours website to get more notification.

What is Trigger?

Trigger is a procedure in database which automatically invokes whenever a special events in Database occurs. Apex triggers enable you to perform custom actions before or after events to records in Salesforce, such as insertions, updates, or deletions.

Apex Triggers
Apex Triggers

When Should we Use Trigger?

  • Complex logic incapable of being processed via declarative artifacts
  • Logic associated with DML
  • Operations on unrelated objects
  • Integration with External Systems

Trigger Events

Trigger Events
Trigger Events

Trigger Context Variable

Variable Usage
isExecuting It tells if code current context is trigger or not
isInsert It returns true if trigger fires on insert operation
isUpdate It returns true if trigger fires on update operation
isDelete It returns true if trigger fires on delete operation
isBefore It returns true if code is running in Before context
isAfter It returns true if code is running in After context
new It holds list of new versions of sObject records
This sObject list is only available in insert, update, and undelete triggers, and the records can only be modified in before triggers
newMap It holds new versions of sObject in key value pair
This map is only available in before update, after insert, after update, and after undelete triggers
old It holds list of old versions of sObject records
This sObject list is only available in update and delete triggers
oldMap It holds old versions of sObject in key value pair
This map is only available in update and delete triggers.
operationType Returns an enum of type System.TriggerOperation corresponding to the current operation. System.TriggerOperation enum are: BEFORE_INSERT, BEFORE_UPDATE, BEFORE_DELETE,AFTER_INSERT, AFTER_UPDATE, AFTER_DELETE, and AFTER_UNDELETE
size The total number of records in a trigger invocation, both old and new.

Demo 1 : Using context variable in Trigger

trigger AccountTrigger on Account (before insert, before update, after update) {
    if(Trigger.isBefore && Trigger.isInsert){
        System.debug('I am in AccountTrigger before insert context');
            for(Account acc :Trigger.new){
                System.debug('New Name'+ acc.Name);
                System.debug('Old Name'+ Trigger.oldMap.get(acc.Id).Name);

Order of Execution.

Order of Execution
Order of Execution

Here is recording of our old session on Order of Execution. Check this blog post to learn more.

Trigger Handler pattern

Check this blog post to learn about which all trigger pattern are available in Salesforce. For Trigger Handler code check this post

Trigger Handler pattern
Trigger Handler Pattern

Trigger Best Practice

1) One Trigger Per Object
2) Logic-less Triggers
3) Context-Specific Handler Methods
4) Bulkify your Code
5) Avoid SOQL Queries or DML statements inside FOR Loops
6) Using Collections, Streamlining Queries, and Efficient For Loops
7) Querying Large Data Sets
8) Use @future Appropriately
9) Avoid Hardcoding IDs

Always remember below points before writing trigger :-
1) Order Of Execution
2) Recursive Trigger
3) Learn about Other Trigger Framework


Episode 5 will be presented by Purushottam Bhaigade on Feb 14, 2020 at 6 PM Indian Standard Time.


Complete below assignment to win $1000 Salesforce Voucher. Click here for rule.

Create Custom object Invoice with field Total Amount
Create child object Invoice Line Item with Lookup relationship to Invoice.
Add price field into Invoice Line Item.
Write trigger on Invoice Line Item which will add some of all child records to parent Invoice

Trigger Handler Pattern

Further Learning

Trigger Framework

Don’t forget to register for our next session on Test Classes. Check this post for all other session detail.

Please note that we have limit of 500 attendees that can join the online sessions. However, recording will be posted on our YouTube channel. Make sure to subscribe our YouTube channel to get notification for video upload.

So, learn at your pace and free will and ace your journey to Salesforce!


  1. Reply
    Ankit Desai says:

    Completed Assignment for Day 5
    I have created one trigger “InvoiceAmountUpdate” and one class “InvoiceAmountUpdateHandler”

  2. Reply
    Aathirai says:

    Completed Day 5 Assignment

  3. Reply
    A Belano says:

    Day 5 Assignment Completed

  4. Reply
    Brisilda says:

    Episode 5 – Demystifying Apex Triggers Assignment Completed!

  5. Reply
    Archit Dutt Sharma says:

    Completed Day 5 assignment

  6. Reply
    Anuj Sahu says:

    Day 5 Assignment is completed

  7. Reply
    Marishell Cruz says:


    • Reply
      Amit Chaudhary says:

      8 more to go

    • Reply
      Pb says:

      Can someone update all the solution?

  8. Reply
    Jaya Iyer says:

    completed assignment 5

  9. Reply
    Pb says:

    Solution plz

    • Reply
      Amit Chaudhary says:

      After contest over

  10. Reply
    Arjinder Kaur says:

    assignment 5 completed

  11. Reply
    Pritam Pramod Dalvi says:

    Assignment 5 Completed

  12. Reply

    Day 5 Assignment is completed

  13. Reply

    Day 5 Assignment is completed

  14. Reply
    Arjinder Kaur says:

    Solution for Assignment : Trigger on Invoice Line Item which will add sum of all child records to parent Invoice:

    trigger AddInvoiceItems on Invoice_Line_Item__c ( after insert, after update, after delete ) {

    List ListIds = new List();

    if ( Trigger.isInsert || Trigger.isUpdate ) {

    for ( Invoice_Line_Item__c item : Trigger.New ) {
    if ( Trigger.isInsert || ( Trigger.isUpdate && Trigger.OldMap.get(item.ID).price__c!=item.price__c) ) {



    for( Invoice_Line_Item__c item : Trigger.Old ) {



    Map TotalPriceMap = new Map();

    for ( Invoice_Line_Item__c item : [ SELECT Id, price__c, invoice__c FROM Invoice_Line_Item__c WHERE invoice__c IN : ListIds ] ) {

    Decimal totalPrice = 0;
    if( TotalPriceMap.containsKey ( item.invoice__c ) )
    totalPrice = TotalPriceMap.get( item.invoice__c );
    totalPrice = totalPrice + item.price__c;

    List updateInvoice = new List();
    for ( Id invoiceId : TotalPriceMap.KeySet() ) {
    Invoice__c inv = new Invoice__c ( Id = invoiceId );
    inv.Total_Amount__c = TotalPriceMap.get( invoiceId );

    if ( updateInvoice.size() > 0 )
    Update updateInvoice;


    • Reply
      kishore goud says:

      HI bro, i have one question, you have declared empty map . since it is empty how you are searching using containskey

      • Reply
        Arjinder Kaur says:

        Thanks for pointing out. It should be like this:

        Map TotalPriceMap = new Map();

        I believe, datatype got missed while I pasted my solution.
        I am sorry about it. I will check and correct it.

        Thanks again!

    • Reply
      Arjinder Kaur says:

      Corrections to the code – Please check comments below

  15. Reply
    kishore goud says:

    HI bro, i have one question, you have declared empty map . since it is empty how you are searching using containskey

    • Reply
      Arjinder Kaur says:

      Facing some issue with code within angle brackets after I posted comment.

      List ListIds = new List(); // Id within angle brackets after List
      Map TotalPriceMap = new Map(); // Id,Decimal within angle brackets after Map
      List updateInvoice = new List(); // Invoice__c within angle brackets after List

  16. Reply
    Arjinder Kaur says:

    Noticed some issues with posted code : I noticed code(data type) within angle brackets got removed after I posted it. I am sorry about this.
    Please add following datatype ( written after backslash ) within angle bracket after List or Map


    List ListIds = new List(); // Add Id within angle brackets after List

    Map TotalPriceMap = new Map(); // Add Id , Decimal within angle brackets after Map

    List updateInvoice = new List(); // Add Invoice__c within angle brackets after List

  17. Reply
    Ankit Desai says:

    Code for Assignment Day 5

    trigger InvoiceAmountUpdate on Invoice_Line_Item__c (after insert,
    after update,
    after delete) {

    String invoiceId = ”;
    if(Trigger.isInsert || Trigger.isUpdate) {
    for(Invoice_Line_Item__c invoiceLineItem : Trigger.new) {
    if(invoiceLineItem.Invoice__c != null) {
    invoiceId = invoiceLineItem.Invoice__c;
    for(Invoice_Line_Item__c invoiceLineItem : Trigger.old) {
    if(invoiceLineItem.Invoice__c != null) {
    invoiceId = invoiceLineItem.Invoice__c;
    if(invoiceId != ”) {


    public class InvoiceAmountUpdateHandler {
    public static void updateInvoiceAmount(String invoiceId) {
    List items = new List();
    items = [select Id,price__c from Invoice_Line_Item__c where Invoice__c = :invoiceId];
    Decimal amount = 0;
    for(Invoice_Line_Item__c item : items) {
    amount = amount + item.Price__c;
    Invoice__c invoice = new Invoice__c();
    invoice.Id = invoiceId;
    invoice.Total_Amount__c = amount;
    update invoice;


    • Reply
      swathi says:

      Hi! I have written a code for trigger assignment task and its working well for insert and update. Can you please tell me whether I need to modify my code for better results..

      Parent: Invoice__c
      Child: Invoice_Line_Item__c

      Trigger code:
      trigger Invoice_Line_Item__cTrigger on Invoice_Line_Item__c (after insert, after Update) {

      if((trigger.IsInsert == true && Trigger.Isafter == true) ||(trigger.IsUpdate == true && Trigger.Isafter == true)){



      public class Invoice_Line_ItemHandler {

      public static list P_id = new list();
      public static decimal amount=0;

      public static void AmoutUpd(list ChildRec){

      for(Student__c Pid : StuRec){

      if(pid.Teacher_name__c != null){

      list Rec = [SELECT Total_amout__c,name,(SELECT Invoice_name__c,price__c FROM Invoice_Line_Item__r) FROM Invoice__c WHERE ID IN :P_id];

      for(Invoice__c a: Rec){

      for(Invoice_Line_Item__c b: a.Invoice_Line_Item__r){

      amount = amount+ b.price__c ;

      a.Total_amout__c = amount;
      update Rec;


  18. Reply
    Jim says:

    I copied the Handler Class from above into the Dev console but I receive Unexpected token ‘List’. error for this statement:
    List items = new List();

    What am i missing here?


  19. Reply
    Kiran says:

    Logic for Trigger
    public class ApexHourTriggerAssignment {

    public static void updateInvoceObjectField(List lstinvln){
    Decimal amount=0;
    Set liStIds = new Set();
    for (Invoice_Line_Up__c ilu :lstinvln) {
    if(ilu.Invoice_Name__c != null) {
    List ListInvoice = [Select id, Total_Amount__c, (select id, price__c from Invoices_Line_up__r)
    from Invoice__c Where Id IN :liStIds];
    ListListInv = new List();
    For(Invoice__c inv : ListInvoice){
    for(Invoice_Line_Up__c ilu1 : inv.Invoices_Line_up__r){
    amount = amount + ilu1.price__c;
    inv.Total_Amount__c = amount;
    update ListInv;

    trigger ApexHourTriggerAssignmentTrigger on Invoice_Line_Up__c (After insert,After Update) {


  20. Reply
    Sagar says:

    My solution for assignment.

    trigger TotalInvoiceAmount on Invoice_Line_Item__c (after insert) {

    Map UniqueInvoiceToUpdate = new map(); // To maintain unique sobject to be updated
    Map TotalAMount = new Map(); // To maintain the updated amount of each invoice sobject

    ListInvoiceToUpdate = new List(); // final list to perform dml update operation
    Invoice__c ParentInvoice;

    for (Invoice_Line_Item__c currentInvoiceItem : Trigger.New) {

    ParentInvoice = [select id, Total_Amount__c from Invoice__c where Id = :currentInvoiceItem.Invoice__c LIMIT 1][0];

    // Check if we have updated total value of invoice in previous iterations:
    if (TotalAmount.get(ParentInvoice.Id) != null) {

    // if yes, add the current amount of invoice line item to the previous updated invoice object.
    // Not that, we have not commit to database yet. Hence we are retrieving updated amount from map and not from sobject’s Total amount field
    ParentInvoice.Total_Amount__c = TotalAmount.get(ParentInvoice.Id) + currentInvoiceItem.Amount__c;
    else {
    // We haven’t saved total amount in map yet.
    // Add current invoice line item amount to total amount of invoice object.
    ParentInvoice.Total_Amount__c += currentInvoiceItem.Amount__c;
    // save updated total amount of invoice object in map
    TotalAmount.put(ParentInvoice.Id, ParentInvoice.Total_Amount__c );

    // update invoice object’s map.
    UniqueInvoiceToUpdate.put(ParentInvoice.Id, ParentInvoice);

    // iterate UniqueInvoiceToUpdate map to put those invoice objects in list.
    for (Invoice__c I : UniqueInvoiceToUpdate.values()){

    // update list.
    update InvoiceToUpdate;

    Any better solution?

Post a comment