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
Ummul FazariaUmmul Fazaria 

update contact trigger

I am trying to create a trigger where contact description will update when account object description is updated and my code is as below: but i am getting an error "Loop must iterate over collection: Map<Id,Account>"

trigger ContactFieldUpdate on Account (after update) {
  Set<ID> setAccId = new Set<ID>();
    List<contact> lstConUpdate = new List<Contact>();
    for(Account accl : Trigger.new)
    {    
            setAccId.add(accl.id);
    }
    
    Map<ID, Account> mapAccount = new Map<ID, Account>([select id,description,(select id,description from contacts ) from account where id in :setAccId ]);
    
    for(Account acc: mapAccount){
        for(Contact con : acc.contacts){
            con.Description = acc.Description;
            lstConUpdate.add(con);
        }
    }
    
     update lstConUpdate;
        
    }


    
    
       
      
        
        

 
Best Answer chosen by Ummul Fazaria
ANUTEJANUTEJ (Salesforce Developers) 
Hi Ummul,

So you can try changing your snippet to something like below and try:
trigger ContactFieldUpdate on Account (after update) {
 if(trigger.isafter && trigger.isupdate)
{ 
    List<contact> lstConUpdate = new List<Contact>();
    set<id> acid = trigger.newmap.keyset();

List<Account> lstAccount = [SELECT Id, description, (SELECT Id, description FROM Contacts) FROM Account where id in :acid];

    for(Account acc: lstAccount){
        for(Contact con : acc.contacts){
            con.Description = acc.description;
            lstConUpdate.add(con);
        }
    }
    if(lstConUpdate.size()>0)
    {update lstConUpdate;}
    }
    }

Edit: I have removed the loop and replaced it with trigger.newmap.keyset() which would be returning the set of id's of new records and used it in the soql, thereby removing a loop.

Let me know if it helps you and close your query by marking it as best answer so that it can help others in the future.  

Thanks.

All Answers

ANUTEJANUTEJ (Salesforce Developers) 
Hi Ummul,

So you can try changing your snippet to something like below and try:
trigger ContactFieldUpdate on Account (after update) {
 if(trigger.isafter && trigger.isupdate)
{ 
    List<contact> lstConUpdate = new List<Contact>();
    set<id> acid = trigger.newmap.keyset();

List<Account> lstAccount = [SELECT Id, description, (SELECT Id, description FROM Contacts) FROM Account where id in :acid];

    for(Account acc: lstAccount){
        for(Contact con : acc.contacts){
            con.Description = acc.description;
            lstConUpdate.add(con);
        }
    }
    if(lstConUpdate.size()>0)
    {update lstConUpdate;}
    }
    }

Edit: I have removed the loop and replaced it with trigger.newmap.keyset() which would be returning the set of id's of new records and used it in the soql, thereby removing a loop.

Let me know if it helps you and close your query by marking it as best answer so that it can help others in the future.  

Thanks.
This was selected as the best answer
Suraj Tripathi 47Suraj Tripathi 47
Hi Ummul.

You can take reference from this below code:-
You are getting the error because you can never iterate the map but yes you can iterate map.keyset() and map.values(). 
trigger ContactFieldUpdate on Account (after update) {
    List<contact> lstConUpdate = new List<Contact>();
    Map<ID, Account> mapAccount = new Map<ID, Account>([select id,description,(select id,description from contacts ) from account where id IN :trigger.new ]);
    
    for(Account acc: mapAccount.values()){
        if(acc.contacts.size()>0){
            for(Contact con : acc.contacts){
                con.Description = acc.Description;
                lstConUpdate.add(con);
            }
        }
    }
    update lstConUpdate;
}
if(acc.contacts.size()>0)  --> If you will not use this condition it throws null pointer exception


In case you find any other issue please mention. 
If you find your Solution then mark this as the best answer. 

Thanks and Regards
Suraj Tripathi
Suraj Tripathi 47Suraj Tripathi 47

Hi Ummul,

You can also try the below code with Best Practices.

trigger AccountTrigger on Account (after update) {
    if(Trigger.isAfter && trigger.isUpdate) { List<Contact> contactList=new List<Contact>([select id,description from Contact where accountid in: trigger.new]);
         for(Contact con:contactList){
            if(trigger.NewMap.get(con.AccountId).description!=null){
                  con.description=trigger.NewMap.get(con.AccountId).description;
            }}                                                            
        Update contactList;
    }

Don't forget to mark it as the Best Answer if your query is solved.

If you have any issues please tell

Thank You