+ Start a Discussion
TS21TS21 

In Trigger how to avoid for loop Inside for loop

I am creating a Trigger that whenever a Contact gets created or inserted the Account Name field will update to a specific account suppose name "xyz".  Right now I have used For loop Inside a For Loop. Is there any way that I can avoid for loop inside for loop? Can I use Map here if yes How?

My current Code is :
trigger AddConToAcc on Contact (before insert) {
list<Account> listAcc = new List<Account>([SELECT Id, Name from Account where name = 'XYZ']);       
    for(Contact con : Trigger.New){
            for(Account acc : listAcc){
                con.AccountId = acc.Id;
                }           
            }
     }
I tried to use a Map but its not working Code mentioned below :
trigger ContToAcc on Contact (before insert) {
    Set<Id> setAccId = New Set<Id>();
       List<Account> acc = New List<Account>([SELECT ID FROM Account WHERE Name = 'XYZ']); 
    for(Account acc1 : acc){
        setAccId.add(acc1.Id);
    }
   Map<Id, Account> mapacc = new Map<Id, Account>([Select Id, Name FROM Account WHERE ID IN :setAccId]);
    for(Contact con : Trigger.New){
        con.Account = mapacc.get(con.Account.Id);        
    }
}
RKSalesforceRKSalesforce
Hi TS21,

Please use below code which has used Map in it. If before insert does not work then please try with after Insert.
trigger AddConToAcc on Contact (before insert) {
	list<Account> listAcc = new List<Account>([SELECT Id, Name from Account where name = 'XYZ']);  
    set<Id> accountIds = New Set<Id>();
	Map<Id, Account> IdAndAccountMap = new Map<Id, Account>();
	list<Account> accountsToUpdate = new list<Account>();
	for(Contact con: Trigger.New){
		accountIds.add(con.AccountId);
	} 
	for(Account acc:[Select id, Name from Account Where Id IN :accountIds]){
		IdAndAccountMap.put(acc.id, acc);
	}
    for(Contact con : Trigger.New){
		IdAndAccountMap.get(AccountId).Name = 'xyz';
		accountsToUpdate.add(IdAndAccountMap.get(AccountId));	
    }
	update accountsToUpdate;
}
Please mark as best answer if helped.

Regards,
Ramakant
 
TS21TS21
Hi Ramakant,

Thanks for your Reply!! However, above provided code doesn't work as listAcc which contains the list of account with name 'xyz' is not used anywhere.

Regards
RKSalesforceRKSalesforce
Please use below code:
trigger AddConToAcc on Contact (before insert) {
	list<Account> listAcc = new List<Account>([SELECT Id, Name from Account where name = 'XYZ']);    
	Map<String, Id> NameandIdMap = new Map<String, Id>();
	for(Account acc: listAcc){
		NameandIdMap.put(acc.Name, acc,Id);
	}
	
    for(Contact con : Trigger.New){
		con.AccountId = NameandIdMap.get('XYZ');          
    }
}

Hope this will help.

Regards,
Ramakant
Prashant Pandey07Prashant Pandey07
Hi TS21,

I believe if you are query with the specific account then it will return only one acocunt..if that is true then we don't have to add another loop to query an account.
 
trigger AddConToAcc on Contact (before insert) {
    list<Account> listAcc = new List<Account>([SELECT Id, Name from Account where name = 'Test 9']);    
   
    for(Contact con : Trigger.New){
        con.AccountId =listAcc.get(0).id;
               
    }
}



Let me know if this helps you...
--
Thanks,
Prashant
Nishant Prajapati 10Nishant Prajapati 10
Hi, Here is my suggestion, Try it and let me know if it works or not
trigger UpdateAccountName on Contact(after insert){
    set<Id> AccountIdSet = new set<Id>();
    List<Account> account2Update = new List<Account>();
    for(Contact con : Trigger.New){
        if(con.AccountId <> null)
            AccountIdSet.add(con.AccountId);
    }
    
    Map<Id,Account> accountMap = new  Map<Id,Account>([Select Id, Name from Account WHERE Id IN: AccountIdSet]);
    for(Contact con : Trigger.New){
        if(con.AccountId <> null && accountMap.containsKey(con.AccountId)){
               accountMap.get(con.AccountId).Name = con.Name; // specify your name for Account, Here I took contact name itself, change it according to your requirement
               account2Update.add(accountMap.get(con.AccountId));
        }
    }
    
    update account2Update;
}

 
Amit Chaudhary 8Amit Chaudhary 8
Please check below post how to avoid multipe for loop with the help of MAP
1) http://amitsalesforce.blogspot.in/2016/09/collection-in-salesforce-example-using.html

Your code is very simple you can use code like below without For Map like below
trigger AddConToAcc on Contact (before insert) 
{
	list<Account> listAcc = new List<Account>([SELECT Id, Name from Account where name = 'XYZ' limit 1]); 
	
    for(Contact con : Trigger.New)
	{
		if(listAcc.size() > 0 ){ // Always check size so that execption will not come
			con.AccountId = listAcc[0].id;
		}	
	}
}

If you Still want to use map only. Check above post and try to convert your code like below
trigger AddConToAcc on Contact (before insert) 
{
	list<Account> listAcc = new List<Account>([SELECT Id, Name from Account where name = 'XYZ' limit 1]); 
	Map<String,Account> mapNameWiseAcc = new Map<String,Account>();
	for(Account acc : listAcc){
		mapNameWiseAcc.put(acc.name,acc);
	}
	
    for(Contact con : Trigger.New)
	{
		if(mapNameWiseAcc.containsKey('XYZ') ) // Always try to use containsKey before get method in Map
		{
			con.AccountId = mapNameWiseAcc.get('XYZ').id;
		}	
	}
}


Let us know if this will help you