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
Pranav ChitransPranav Chitrans 

Small query on trigger.OldMap

Actually I am having little query on trigger.OldMap functionality.. I had written one trigger... And I am clear with some concepts but having little doubt on :
for(Contact con : mapACC.get(updatedAcc.Id).contacts)
If I am removing ".contacts"(dot contacts) it shows error that "Loop must iterate over a collection type: Account". I want ot know what is the role of .contacts here...
some part of my code I am pasting to clear my instances that I had created for my trigger
if(trigger.isUpdate && trigger.isAfter)
 {
  Map<Id,Account> mapACC = new Map<Id,Account>(trigger.oldMap);
  List<Contact> newCon = new List<Contact>();
  for(Account updatedAcc : trigger.New)
  {
   Account oldAcc = trigger.oldMap.get(updatedAcc.Id);
   if(mapACC.ContainsKEY(updatedAcc.Id) && oldAcc.Name != updatedAcc.Name)
   {
    for(Contact con : mapACC.get(updatedAcc.Id).contacts)
    {
     con.LastName = updatedAcc.Name;
     newCon.add(con);
    }
   }
  }
  update newCon;
 }

 
Best Answer chosen by Pranav Chitrans
Abhishek BansalAbhishek Bansal
Hi Pranav,

Your accMap is holding values like :
Key : Id i.e account id
Value : Account i.e. single record of Account

And the account record that is stored in Map value also holds a inner list of all the contacts that is related to the same Account.

When you are using accMap.get(updatedAcc.id) than this will return you the Account record with all of its fields and related Contact list.
So if you want to use any field of that particular Account than you have to use a . (dot) operator and than define the name of field which you want to access.

So by using accMap.get(updatedAcc.id).contacts you are accessing all the contacts that are related to the particular Account whose id you have passed in map.

Let me know if you need more information or clarification on this

Thanks,
Abhishek

All Answers

Alexander TsitsuraAlexander Tsitsura

Hi Pranav,
 

After execute "mapACC.get(updatedAcc.Id)" you get account record from map. Contacts fields for Account object contacts list of all related child contacts, and you interate throught all children related contacts, and change last name for it.


As a common practice, if your question is answered, please choose 1 best answer. 
But you can give every answer a thumb up if that answer is helpful to you.

Thanks,
Alex

AshlekhAshlekh
Hi,

You can use below code.
if(trigger.isUpdate && trigger.isAfter)
{
	Map<id,Account> updatedAccountMap = new Map<id,Account>();
	Map<Id,Account> mapACC = new Map<Id,Account>(trigger.oldMap);
	List<Contact> newCon = new List<Contact>();
	for(Account updatedAcc : trigger.New)
	{
		Account oldAcc = trigger.oldMap.get(updatedAcc.Id);
		if(mapACC.ContainsKEY(updatedAcc.Id) && oldAcc.Name != updatedAcc.Name)
		{
			updatedAccountMap.add(updatedAcc.Id,updatedAcc);
		}
	}
	if(updatedAccountMap.size()>0)
	{	  
		for(Contact con : [select id, Lastname from Contact where accountid in :updatedAccountMap.keySet()]){
			con.LastName = updatedAccountMap.get(con.accountID).Name;
			newCon.add(con);
		}
		if(newCon.size()>0)
			update newCon;
	}
}
There are other approach in code to do this also.

Enjoy apex and salesforce.

-Thanks
Ashlekh Gera
 
Abhishek BansalAbhishek Bansal
Hi Pranav,

Your accMap is holding values like :
Key : Id i.e account id
Value : Account i.e. single record of Account

And the account record that is stored in Map value also holds a inner list of all the contacts that is related to the same Account.

When you are using accMap.get(updatedAcc.id) than this will return you the Account record with all of its fields and related Contact list.
So if you want to use any field of that particular Account than you have to use a . (dot) operator and than define the name of field which you want to access.

So by using accMap.get(updatedAcc.id).contacts you are accessing all the contacts that are related to the particular Account whose id you have passed in map.

Let me know if you need more information or clarification on this

Thanks,
Abhishek
This was selected as the best answer
Pranav ChitransPranav Chitrans
hey Abhishek Bansal,
THANK YOU so much for Such a nice explanation...  But still having a little bit more to clear me..
 DOUBT NO.1 : As you said  "Map value also holds a inner list of all the contacts "
My query : Map value will hold the only that contact which will be associated to that Account becz of lookup reltn with contact???... If it is so.. then how the record is being come to know that this is related to this conatct or something like that.. how we are linking here the account to contact..?

DOUBT NO.2 : When you are using accMap.get(updatedAcc.id) than this will return you the Account record with all of its fields and related Contact list.
MY QUERY : a).  How the mapAcc will return the related contact.. it will return the list of record of account That it is very clear, but how the list of Contact will be returned or linked to it...??
                      b). At line 10 in my code for(Contact con : mapACC.get(updatedAcc.Id).contacts) why we cant use trigger.New instead of mapACC.get(updatedAcc.Id).contacts .
little bit confused.. by using this we are putting the updated record Account Id to instance Con??/ iS it something like that...

DOUBT NO.3 : So if you want to use any field of that particular Account than you have to use a . (dot) operator and than define the name of field which you want to access.
MY QUERY : If we want to acces any object of that class.. we use with the dot(.) that i understnad, here also going the same logic.. but iwe used .Contacts.. which is another class..or u can say object.. If we want to acces the name filed on account we would use Account.Name.. that is clear/... but .Contacts???


It will be my goodluck if u would find the time to answer my lengthy questions..
Thankxx in advacne
 
Abhishek BansalAbhishek Bansal
Hi Pranav,

Let me clear your all doubts :
Fisrt of all i want to let you know that your accMap is surely constructed with the below query :
accMap = new Map<Id,Account>([Select id,Name,(Select id,name from contacts) from Account]);
which means that this map will hold key as Account Id and value as Accound Record and that Account Record will itself holds a list of Contact that is associated with it or you can say all the child contacts of that Account.

Now coming to your various doubts :
Doubt No. 1 : There is a standard lookup field on Contact object i.e AccountId which ensures that a contact is related to a particular Account or not. So if an account has some contacts related to it than your account record will hold values in contacts list for all of those contacts that are associated with it.

Doubt No. 2 : mapAcc.get(AccountId).contacts will return a list of all the contacts that are related with the account. If you use trigger.new than this will return all the contacts that are currently being inserted or updated. So it depends totally on your working scenarios that whether you want to use trigger.new or You want to use Contacts based on their rekationship with Account.

Doubt No. 3 : When you use inner queries in your Soql than the child relationship name which you use for your child objects will act as an field name and by using that child relationship name you can access the child list from instance of a parent record.
In this particular case your query is : [Select id,Name,(Select id,name from contacts) from Account] where contacts is a child relationship name so if you want to access the contact list of a particular account than you have to use .contacts.
Please do not misx it up with the classes and Objects instances.It is a simple SOQL field or you can say that it is a child list for a parent record.


Hope everything is clear to you.
If you still have any issue than you can surely ask for more help or information on this.

Thanks,
Abhishek