function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Alex MezaAlex Meza 

How to get two triggers that affect each other to run together, without getting a recursive or loop error.

I was able to write 2 triggers for two different custom objects TGA_Email_List__c and Voter_File__c. Both triggers look for a match between the two custom objects, of first name, last name, and zipcode and if a match found then one trigger auto populates the lookup field of Voter_ID_del__c on TGA_Email_List custom object, while the other trigger auto populates the look up field of Email_ID_del__c on the Voter_File__c object. 

These triggers work great if I run them indvidually, having only one of them active. However, when I have both of the triggers active they run into a recusrvie error because both are set to run when a reocrd in that object is update or created, thus creating a constant error and rescursive loop that goes on forever. Both Triggers are below.

Trigger 1:
trigger EmailtoVoterFile on TGA_Email_List__c (before insert,before update,after insert,after update)
{ if(checkRecursive.runOnce())
{
    Set<String> set_Str = new Set<string>();
    Map<String,Voter_File__c> mp_voterfileObj;
    
    if(Trigger.isAfter && Trigger.isUpdate)
    {
        for(Voter_File__c voterfileobj : [Select ID,First_Name__c, Last_Name__c,ZipCode__c, Email_ID_del__c From Voter_File__c])
        {
                    if(mp_VoterfileObj==null)
                        mp_VoterFileObj = new Map<String,Voter_File__c>();
            
            mp_VoterFileobj.put(voterfileobj.First_Name__c +''+voterfileobj.Last_Name__c +''+voterfileobj.Zipcode__c,voterfileobj);

 
                    }
        
        for(TGA_Email_List__c TGAEmailListobj : Trigger.new)
    {
        if(mp_VoterFileObj!=null && mp_Voterfileobj.containsKey(TGAEmailListobj.First_Name__c +''+ TGAEmailListobj.Last_Name__c +''+ TGAEmailLIstobj.Zipcode__c))

        {

       mp_Voterfileobj.get(TGAEmailListobj.First_Name__c +''+ TGAEmailLIstobj.Last_Name__c +''+ TGAEmailListobj.Zipcode__c).Email_ID_del__c = TGAEmailListobj.id;

}

}
 
if(mp_VoterFileObj!=null && mp_VoterFileObj.values()!=null)
        update mp_VoterFileObj.values();

    }
}
}

Trigger 2:
trigger VoterIDUpdate on Voter_File__c (before insert,before update,after insert,after update) 
{ if(checkRecursive.runOnce())
{
    Set<String> set_Str = new Set<string>();
    Map<String,TGA_Email_List__c> mp_EmailList;
    
    if(Trigger.isAfter && Trigger.isUpdate)
    {
        for(TGA_Email_List__c EmailList : [Select ID,First_Name__c, Last_Name__c,ZipCode__c, Voter_ID_del__c From TGA_Email_List__c])
        {
                    if(mp_EmailList==null)
                        mp_EmailList = new Map<String,TGA_Email_List__c>();
            
            mp_EmailList.put(EmailList.First_Name__c +''+EmailList.Last_Name__c +''+EmailList.Zipcode__c,EmailList);

 
                    }
        
        for(Voter_File__c VoterID : Trigger.new)
    {
        if(mp_EmailList!=null && mp_EmailList.containsKey(VoterID.First_Name__c +''+ VoterID.Last_Name__c +''+ VoterID.Zipcode__c))

        {

       mp_EmailList.get(VoterID.First_Name__c +''+ VoterID.Last_Name__c +''+ VoterID.Zipcode__c).Voter_ID_del__c = VoterID.id;

}

}
 
if(mp_EmailList!=null && mp_EmailList.values()!=null)
        update mp_EmailList.values();

    }
}
}

I then wrote a class and included a code in the triggers that would solve this issue and have it only run once if it was recusrive, however when I did this then and activated both triggers none of the fields were being auto populated if a match was found, also there was no error being thrown out. 

Class:
public class checkRecursive {
    private static boolean run = true;
    public static boolean runOnce(){
    if(run){
     run=false;
     return true;
    }else{
        return run;
    }
    }  
}

My question is how do I get this to work so that I can have both of lookup fields auto populate based on a match on both custom objects, while also not getting a recuring error. 

Please, help I am stuck, Thanks!
 
Best Answer chosen by Alex Meza
Amit Singh 1Amit Singh 1
Use below code.

Helper class
public class checkRecursive {
    public static boolean runOnce = false;
}

Trigger 1-
trigger VoterIDUpdate on Voter_File__c (before insert,before update,after insert,after update) 
{ if(checkRecursive.runOnce){ return;}
    Set<String> set_Str = new Set<string>();
    Map<String,TGA_Email_List__c> mp_EmailList;
    
    if(Trigger.isAfter && Trigger.isUpdate)
    {
        for(TGA_Email_List__c EmailList : [Select ID,First_Name__c, Last_Name__c,ZipCode__c, Voter_ID_del__c From TGA_Email_List__c])
        {
                    if(mp_EmailList==null)
                        mp_EmailList = new Map<String,TGA_Email_List__c>();
            
            mp_EmailList.put(EmailList.First_Name__c +''+EmailList.Last_Name__c +''+EmailList.Zipcode__c,EmailList);

 
                    }
        
        for(Voter_File__c VoterID : Trigger.new)
    {
        if(mp_EmailList!=null && mp_EmailList.containsKey(VoterID.First_Name__c +''+ VoterID.Last_Name__c +''+ VoterID.Zipcode__c))

        {

       mp_EmailList.get(VoterID.First_Name__c +''+ VoterID.Last_Name__c +''+ VoterID.Zipcode__c).Voter_ID_del__c = VoterID.id;

}

}
 
if(mp_EmailList!=null && mp_EmailList.values()!=null)
        checkRecursive.runOnce = true;
        update mp_EmailList.values();

    }
}

Trigger 2
trigger EmailtoVoterFile on TGA_Email_List__c (before insert,before update,after insert,after update){ if(checkRecursive.runOnce){return;}
    Set<String> set_Str = new Set<string>();
    Map<String,Voter_File__c> mp_voterfileObj;
    
    if(Trigger.isAfter && Trigger.isUpdate)
    {
        for(Voter_File__c voterfileobj : [Select ID,First_Name__c, Last_Name__c,ZipCode__c, Email_ID_del__c From Voter_File__c])
        {
                    if(mp_VoterfileObj==null)
                        mp_VoterFileObj = new Map<String,Voter_File__c>();
            
            mp_VoterFileobj.put(voterfileobj.First_Name__c +''+voterfileobj.Last_Name__c +''+voterfileobj.Zipcode__c,voterfileobj);

 
                    }
        
        for(TGA_Email_List__c TGAEmailListobj : Trigger.new)
    {
        if(mp_VoterFileObj!=null && mp_Voterfileobj.containsKey(TGAEmailListobj.First_Name__c +''+ TGAEmailListobj.Last_Name__c +''+ TGAEmailLIstobj.Zipcode__c))

        {

       mp_Voterfileobj.get(TGAEmailListobj.First_Name__c +''+ TGAEmailLIstobj.Last_Name__c +''+ TGAEmailListobj.Zipcode__c).Email_ID_del__c = TGAEmailListobj.id;

}

}
 
if(mp_VoterFileObj!=null && mp_VoterFileObj.values()!=null)
        checkRecursive.runOnce = true;
		update mp_VoterFileObj.values();

    }
}

Let us know if this helps :)

Thanks!
Amit Singh

All Answers

Amit Singh 1Amit Singh 1
Use below code.

Helper class
public class checkRecursive {
    public static boolean runOnce = false;
}

Trigger 1-
trigger VoterIDUpdate on Voter_File__c (before insert,before update,after insert,after update) 
{ if(checkRecursive.runOnce){ return;}
    Set<String> set_Str = new Set<string>();
    Map<String,TGA_Email_List__c> mp_EmailList;
    
    if(Trigger.isAfter && Trigger.isUpdate)
    {
        for(TGA_Email_List__c EmailList : [Select ID,First_Name__c, Last_Name__c,ZipCode__c, Voter_ID_del__c From TGA_Email_List__c])
        {
                    if(mp_EmailList==null)
                        mp_EmailList = new Map<String,TGA_Email_List__c>();
            
            mp_EmailList.put(EmailList.First_Name__c +''+EmailList.Last_Name__c +''+EmailList.Zipcode__c,EmailList);

 
                    }
        
        for(Voter_File__c VoterID : Trigger.new)
    {
        if(mp_EmailList!=null && mp_EmailList.containsKey(VoterID.First_Name__c +''+ VoterID.Last_Name__c +''+ VoterID.Zipcode__c))

        {

       mp_EmailList.get(VoterID.First_Name__c +''+ VoterID.Last_Name__c +''+ VoterID.Zipcode__c).Voter_ID_del__c = VoterID.id;

}

}
 
if(mp_EmailList!=null && mp_EmailList.values()!=null)
        checkRecursive.runOnce = true;
        update mp_EmailList.values();

    }
}

Trigger 2
trigger EmailtoVoterFile on TGA_Email_List__c (before insert,before update,after insert,after update){ if(checkRecursive.runOnce){return;}
    Set<String> set_Str = new Set<string>();
    Map<String,Voter_File__c> mp_voterfileObj;
    
    if(Trigger.isAfter && Trigger.isUpdate)
    {
        for(Voter_File__c voterfileobj : [Select ID,First_Name__c, Last_Name__c,ZipCode__c, Email_ID_del__c From Voter_File__c])
        {
                    if(mp_VoterfileObj==null)
                        mp_VoterFileObj = new Map<String,Voter_File__c>();
            
            mp_VoterFileobj.put(voterfileobj.First_Name__c +''+voterfileobj.Last_Name__c +''+voterfileobj.Zipcode__c,voterfileobj);

 
                    }
        
        for(TGA_Email_List__c TGAEmailListobj : Trigger.new)
    {
        if(mp_VoterFileObj!=null && mp_Voterfileobj.containsKey(TGAEmailListobj.First_Name__c +''+ TGAEmailListobj.Last_Name__c +''+ TGAEmailLIstobj.Zipcode__c))

        {

       mp_Voterfileobj.get(TGAEmailListobj.First_Name__c +''+ TGAEmailLIstobj.Last_Name__c +''+ TGAEmailListobj.Zipcode__c).Email_ID_del__c = TGAEmailListobj.id;

}

}
 
if(mp_VoterFileObj!=null && mp_VoterFileObj.values()!=null)
        checkRecursive.runOnce = true;
		update mp_VoterFileObj.values();

    }
}

Let us know if this helps :)

Thanks!
Amit Singh
This was selected as the best answer
Alex MezaAlex Meza
Awesome thanks this works out perfectly!