Deep Diving in Triggers #Post 3

As we have discussed in previous posts what trigger is,when to use it or not to use it,about context variables and events.

These are the links which you can refer.

What is Trigger

Uses of triggers, Context Variables  & Events of triggers

Moving forward it’s time to learn about use of triggers for related objects.

Let’s take an example in which a field on Account named as No. of Contacts. Based on the value it contains,the same number of contacts will be created. Take a look on the code.

trigger createContact on Account (after insert, after update){

    List<contact> contlist=new List<contact>();

    for(Account a:Trigger.new){

        integer i=0;

        if(a.No_of_Contact__c!=null)

            if((trigger.isUpdate && a.No_of_Contact__c !=  

Trigger.oldMap.get(a.id).No_of_Contact__c) || trigger.isInsert)

                while(i<a.No_of_Contact__c){

                    contact c=new contact();

                    c.LastName='Cont Of '+a.Name+'-'+i;

                    c.AccountId=a.id;

                    contlist.add(c);

                    i++;

                }       

    }

   

    if(contlist.size()>0)

        insert contlist;

}

In this code,contact list is used and null check is used to check the field No. of Contacts is not empty. This trigger will fire on after insert because account id will not be there in case of before insert. In case of update, old map is also checked to prevent the trigger from getting fire every time there is change in account.There is no need to check old map in case of insert, that’s why it is not checked for insert event. You can also look for the best practice in code which is, contact list is used to add the contacts that are to be inserted and then the DML(insertion) is performed outside the loop which will prevent the hitting of Governor Limit in Salesforce.

Next thing of consideration about triggers is, it should be bulkify trigger.The term bulkify trigger specifies the trigger which can process large number of records efficiently and most importantly without hitting Governor Limits of Salsesforce.It is one of the best practices of Salsesforce that you should always write bulkify trigger.

There is scenario which helps you to understand why it is one of the best practices, triggers operate on one record if the action that fired the trigger originates from the user interface. But if the origin of the action is bulk DML or the API, the trigger operates on multiple records rather than single record which will hit the governor limit.

From above we got an idea about what the bulkify trigger is. Why it is one of the best practices of Salsesforce. Now the question is How to write bulkify triggers?

Use map in writing trigger which help to reduce loop within loop

Suppose, there is an scenario every time a lead is created, an account will be created or updated on the basis of email. if lead’s email is in any existing account’s email then trigger will update the account name to lead’s  last name, if lead’s email doesn’t belong to any account then the new account should be created with name as lead lastname and email as a lead’s email.

Map in Salesforce

From above code,you can see on line 11 & 12 ,there is nested loop(for inside for). Although,this code will work fine but it will not be considered as best practice and also in case of bulkify triggers it can hit the Governor Limits of Salesforce. This is the reason why we shouldn’t use nested loops.

We can counter this problem by using maps in triggers which you can see from below code.

trigger emailAcc on Lead (before insert) {
    set <string> emailset=new set <string>();
    for(lead ld: Trigger.New){
        if(ld.email!=null){
            emailset.add(ld.email);
        }
    }
    
    Map<String,Account> emailmap=new Map<String,Account>();
    if(emailset!=null && emailset.size()>0){
        list<Account> aclist=[Select Id,name,email__c from Account where email__c in:emailset];
    
    if(aclist.size()>0){
        for(Account a: aclist)
            emailmap.put(a.email__c,a);
        }
    }
    
    list<Account> upsertlist=new List<Account>();
    for(lead ld: Trigger.New){
        Account acc = new Account();
        if(emailmap.size()>0 && emailmap.containsKey(ld.email)){
            acc = emailmap.get(ld.email);
            acc.name=ld.LastName;
            upsertlist.add(acc);
        }else{
            acc.Name= ld.LastName;
            acc.email__c = ld.email;
            upsertlist.add(acc);
        }
    }
    if(upsertlist.size()>0){
        upsert upsertlist;    
    }
}

In above code,you can see, I have used a map from Email Id to Account for existing getting existing account based on the Email Id of the inserting leads. By using map I got the existing account and removed the nested loop.

So that’s why we should use map in triggers.

Use Set inspite of list as list can hold duplicate values

Put SOQL query directly in for loop condition without using list to get query result and then iteration of list

Let’s take an example , We want to find all account which are having name like ‘Kumar’.

List<Account> accountList = [SELECT Id,Name FROM Account where Name LIKE '%Kumar%'];

for(Account acc : accountList){ 
    
   //Business Logic
}

For that purpose we define a variable accountList to store the query results. Then we use that variable in LOOP. It is consuming extra space and heap size which is obviously not considered as best practice. In spite of that we can directly use SOQL.

for(Account acc :  [SELECT Id,Name FROM Account]){     

   //Business Logic
}

 

 

 
We will discuss more about Trigger Handler and recursive Trigger in the next post.
Until then do whatever you want to do in code.

All rights reserved. No part of this Post may be copied, distributed, or transmitted in any form or by any means, without the prior written permission of the website admin, except in the case of brief quotations embodied in critical reviews and certain other noncommercial uses permitted by copyright law. For permission requests, write to the owner, addressed “Attention: Permissions Coordinator,” to the admin @coderinme

Leave a reply:

Your email address will not be published.