0

I'm working on a trigger to update the account based on the first contact related to the parentaccount, but I'm having some problems when I try to compiling it. The message that are appearing is that a variable doesn't exists, I'm noob in coding and would like to know what i'm doing wrong and also know how to avoid this kind of problem in the future...

trigger AddDomain_AccountToContact on Account (before insert) {    
    List <Account> accList = new List <Account>();
    Set <Id> acc_Ids = new Set <Id>();
    
    for (Account account : trigger.new){
       Account oldAccount = Trigger.oldMap.get(account.id); 
       
        if(account.Unique_Domains__c != Null && (account.Ativo__c == True && oldAccount.Ativo__c == False 
         || account.Piloto_Zendesk__c == True && oldAccount.Piloto_Zendesk__c == False )){
             List<Account> accQueryList = [Select Id, Unique_Domains__c from Account where Id IN: acc_Ids]; 
         }
        
        for(Account a : accQueryList) {  
            String AccountDomain = '';
            List<Contact> contactList = [select Id, Domain__c, AccountId 
                                     from Contact WHERE AccountId in : acc_Ids];
            Integer contactListSize = contactList.size();
            Contact firstContact = contactList[0];
            AccountDomain = firstContact.Domain__c;
            a.Unique_Domains__c = AccountDomain;
            accList.add(a);
        }
    }
    update accList; 
}

The variable that doesn't exists is the "AccQueryList" inside on the loop "for(Account a : accQueryList)"

Thanks in advance!

4

Queries inside of loops are bad, but we'll get to that later.

The issue here is that you defined accQueryList inside of an if block. Once you left that if block, the accQueryList was no longer in scope (and therefore cannot be used).

bad

if(<conditions>){
    // myList is defined inside the scope of this if block, and cannot be used outside
    //   of it
    List<SObject> myList = [query];
}

// This results in an error
for(SObject obj :myList){
}

good

// Define the list outside of the if
List<SObject> myList;
if(<conditions>){
    // You can populate the list inside of the if block
    mylist = [query];
}

// Because the list was not defined in an inner scope that we have left, we
//   can still use it here (and it'll still have the data populated from inside
//   the 'if', assuming we satisfied the conditions to enter that 'if' block
for(SObject obj :myList){
}

To get around the "query inside of a loop" problem, the typical approach is iterate-gather-query

// Define a collection to hold the things you want to use to query
Set<Id> parentAcctIds = new Set<Id>();

// Iterate over your data
for(Account a :trigger.new){
    // Gather your target information
    parentAcctIds.add(a.ParentId);
}

// Then execute your query
// In this case, you can likely get away with simply storing the result in 
//   a Map<Id, Account>
// We can use a parent-child subquery to obtain the contacts related to an account.
// You may have to adjust it depending on what you use to define "the first contact"
Map<Id, Account> parentsWithContact = new Map<Id, Account>([SELECT Id, (SELECT Id, Domain__c FROM Contacts ORDER BY CreatedDate ASC LIMIT 1) FROM Account WHERE Id IN :parentAcctIds]);

From there, you can iterate over your child accounts and get at the relevant data in the parentsWithContact map (assuming that your child accounts have parentId populated). It'd just be something like String domain = parentsWithContact.get(acct.ParentId).Contacts[0].Domain__c;

The details will differ depending on exactly what you're trying to do1, but that should give you a good jumping-off point.

1: if you're trying to get unique domain values, using a Set<String> and then using that to create a List<String> to feed into String.join() is the way I'd go about it. Your current code/description makes it hard to know if that's the correct thing to recommend though. Even if it were, that's probably something that should be its own question

-2

I have gone through your code and found that you are getting this error because you have written a query inside IF condition block which limits its scope, to resolve this please write your query outside the loop.

trigger AddDomain_AccountToContact on Account (before insert) {    
    List <Account> accList = new List <Account>();
    Set <Id> acc_Ids = new Set <Id>();
     List<Account> accQueryList = [Select Id, Unique_Domains__c from Account where Id IN: acc_Ids]; 
     List<Contact> contactList = [select Id, Domain__c, AccountId  from Contact WHERE AccountId in : acc_Ids];
      for (Account account : trigger.new){
       Account oldAccount = Trigger.oldMap.get(account.id); 
       if(account.Unique_Domains__c != Null && (account.Ativo__c == True && oldAccount.Ativo__c == False 
         || account.Piloto_Zendesk__c == True && oldAccount.Piloto_Zendesk__c == False )){
           for(Account a : accQueryList) {  
            String AccountDomain = '';
            Integer contactListSize = contactList.size();
            Contact firstContact = contactList[0];
            AccountDomain = firstContact.Domain__c;
            a.Unique_Domains__c = AccountDomain;
            accList.add(a);
        }  
         }
     }
    update accList; 
}

Hope this explanation will resolve your query.

1
  • 1
    This code does not cure the issues in the original post and preserves at least one existing bug. The currently upvoted answer addresses some of these issues. – David Reed Jan 27 at 21:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.