You need to sign in to do that
Don't have an account?

Trigger question
OK I'm pulling my hair out. I'm trying to access a field from the account object after a contact is inserted. Here's the generic code:
trigger contactTest on Contact(after Insert)
{
//Create list and set
List<Contact> listContact = new List<Contact>();
Set<Id> setContact = new Set<Id>();
//Loop through trigger items
For(Contact loopContact : Trigger.new)
{
//Create new contact for updating
Contact newContact = new Contact(Id = loopContact.Id);
//Get field from Account
newContact.FieldFromAccount = loopContact.Account.FieldFromAccount;
//Make sure distinct list of contacts
if(!(setContact.contains(loopContact.Id))
{
listContact.add(newContact);
setContact.add(newContact.Id);
}
}
//Update list of Contacts
update listContact;
}
The field comes up as null even though it's populated. It's a checkbox. What am I doing wrong?
What a curious design pattern. I've never seen anyone try to update contacts like that before - creating a new one and setting the ID then doing an update. It seems unlikely that would work. You can just update the objects directly and then call update - you don't need to create a new Contact object.
Anyway, in terms of loopContact.Account.FieldFromAccount being null - that's an easy one. A trigger does not populate the entire object relationship tree.
What you need to do is loop through the contacts and grab a Set of AccountIDs that are used by the contacts.
Then use a SOQL query to retreive the fields - something like
Map<ID, Account> accounts = new Map<ID, Account>([SELECT ID, FieldFromAccount from Account where ID in :setofaccountids]);
Then you do the assignment, something like this:
List<Contact> contactstoupdate = new List<Contact>();
For(Contact loopContact : Trigger.new)
{
if(loopContact.AccountID!=null){
loopContact.FieldFromAccount = accounts.get(loopContact.AccountID).FieldFromAccount;
contactstoupdate.add(loopContact);
}
}
update contactstoupdate;
As you see - no need to create a new contact. Accounts aren't required for contact, so you need to test for a valid AccountID both here, and when you create the Set of AccountIDs earlier.
This code is not tested - so there may be typos or syntax errors, but the approach is sounds.
Good luck
Dan
All Answers
What a curious design pattern. I've never seen anyone try to update contacts like that before - creating a new one and setting the ID then doing an update. It seems unlikely that would work. You can just update the objects directly and then call update - you don't need to create a new Contact object.
Anyway, in terms of loopContact.Account.FieldFromAccount being null - that's an easy one. A trigger does not populate the entire object relationship tree.
What you need to do is loop through the contacts and grab a Set of AccountIDs that are used by the contacts.
Then use a SOQL query to retreive the fields - something like
Map<ID, Account> accounts = new Map<ID, Account>([SELECT ID, FieldFromAccount from Account where ID in :setofaccountids]);
Then you do the assignment, something like this:
List<Contact> contactstoupdate = new List<Contact>();
For(Contact loopContact : Trigger.new)
{
if(loopContact.AccountID!=null){
loopContact.FieldFromAccount = accounts.get(loopContact.AccountID).FieldFromAccount;
contactstoupdate.add(loopContact);
}
}
update contactstoupdate;
As you see - no need to create a new contact. Accounts aren't required for contact, so you need to test for a valid AccountID both here, and when you create the Set of AccountIDs earlier.
This code is not tested - so there may be typos or syntax errors, but the approach is sounds.
Good luck
Dan
Awesome. Thanks, Kibitzer!!