You need to sign in to do that
Don't have an account?
DMelsh1
Need help fixing an error in trigger
Hey everyone,
I am trying to create a trigger to pull a Contacts Owner's Email and put it into an icontacts object. This is what I have but its erroring out on the second line (expecting a semi-colon, found 'OwnerIds').
trigger iContactEmailAlert on iContactforSF__iContact_Message_Statistic__c ( Before Insert, Before Update ) {
Set OwnerIds = New Set();
For ( iContactforSF__iContact_Message_Statistic__c a : Trigger.New)
{
//Adding the Owner's ids into a set
OwnerIds.Add ( a.Contact.OwnerID) ;
}
//Getting related contact owner's email address
Map conOwnerEmail = New Map( [Select Email From User Where ID IN:OwnerIds ] );
For ( iContactforSF__iContact_Message_Statistic__c a : Trigger.New)
{
//Populating the related contact's email address using Map functionality
a.ContactOwnerEmail__c = conOwnerEmail.get(a.Contact.OwnerID).Email ;
}
}
I also need a test code after this. I still fairly new to coding.
Thanks for the help.
Dan
I am trying to create a trigger to pull a Contacts Owner's Email and put it into an icontacts object. This is what I have but its erroring out on the second line (expecting a semi-colon, found 'OwnerIds').
trigger iContactEmailAlert on iContactforSF__iContact_Message_Statistic__c ( Before Insert, Before Update ) {
Set OwnerIds = New Set();
For ( iContactforSF__iContact_Message_Statistic__c a : Trigger.New)
{
//Adding the Owner's ids into a set
OwnerIds.Add ( a.Contact.OwnerID) ;
}
//Getting related contact owner's email address
Map conOwnerEmail = New Map( [Select Email From User Where ID IN:OwnerIds ] );
For ( iContactforSF__iContact_Message_Statistic__c a : Trigger.New)
{
//Populating the related contact's email address using Map functionality
a.ContactOwnerEmail__c = conOwnerEmail.get(a.Contact.OwnerID).Email ;
}
}
I also need a test code after this. I still fairly new to coding.
Thanks for the help.
Dan
a.ContactOwnerEmail__c = conOwnerEmail.get(a.iContactforSF__Contact__c.Owner.ContactId).Email;
So we need something were we can pass a.iContactforSF__Contact__c and end up with the related .Owner.ContactId
so in the .Owner.ContactId loop, we need to maintain the association with the a.iContactforSF__Contact__c. To do that we need to throw a map in there,
map<id, id> contactToOwneIDMap = new map<id,id>();
For ( Contact cont : [Select ID, owner.ContactID, Email from Contact where ID in :contactIDs])
{
//Adding the Owner's ID from contact into a set
OwnerIds.add(cont.Owner.ContactID);
contactToOwnerIDMap.put(cont.id, cont.owner.contactID);
}
Then we change our end goal so we can line everything up
a.ContactOwnerEmail__c = conOwnerEmail.get(contactToOwnerIDMap.get(a.iContactforSF__Contact__c)).Email;
Though really, we could simplify it by just getting the email as well in the contact query
map<id, string> contactToOwnerEmailMap = new map<id,string>();
For ( Contact cont : [Select ID, owner.ContactID, owner.Contact.Email from Contact where ID in :contactIDs])//when possible don't assign a separate variable to store the query then iterate through it. Putting the query directly into the loop saves you heap space so you are less likely to run into the memory governor limits.
{
//create a contactMap with the Owner 's email in it
contactToOwnerIDMap.put(cont.id, cont.owner.Contact.Email);
}
...
//cut out the other query since it's no longer needed
...
a.ContactOwnerEmail__c =contactToOwnerEmailMap.get(a.iContactforSF__Contact__c);
Though in reality, now that i think about it a bit more, chances are you don't need this code at all and could just turn ContactOwnerEmail__c into a formula field that does it.
All Answers
set<id> OwnerIds = new set<id>();// =)
Map<id, User> conOwnerEmail = new Map<id, User>([Select Email From User Where ID IN:OwnerIds ]);
trigger iContactEmailAlert on iContactforSF__iContact_Message_Statistic__c ( Before Insert, Before Update ) {
set<id> OwnerIds = new set<id>();
For ( iContactforSF__iContact_Message_Statistic__c a : Trigger.New)
{
//Adding the Owner's ids into a set
OwnerIds.Add ( a.iContactforSF__Contact__r.Owner.ContactId) ;
}
//Getting related contact owner's email address
Map<id, User> conOwnerEmail = new Map<id, User>([Select Email From User Where ID IN:OwnerIds ]);
For ( iContactforSF__iContact_Message_Statistic__c a : Trigger.New)
{
//Populating the related contact's email address using Map functionality
a.ContactOwnerEmail__c = conOwnerEmail.get(a.iContactforSF__Contact__r.Owner.ContactId).Email ;
}
}
Thanks for the help so for.
Dan
OwnerIds.Add ( a.iContactforSF__Contact__r.Owner.ContactId) ;
Trigger.New doesn't give you related objects... in this case the stuff hanging off a.iContactforSF__Contact__c. I think if you run it you'll see that OwnderIds.isEmpty()==true
You'll have to do a separate soql.
set<ID> contactIDs;
For ( iContactforSF__iContact_Message_Statistic__c a : Trigger.New)
{
//Adding the Owner's ids into a set
contactIDs.Add ( a.iContactforSF__Contact__c) ;
}
for ( Contact cont : [Select ID, owner.ContactID from Contact where ID in :contactIDs])[
OwnerIds.add(cont.Owner.ContactID);
}
You'll also have to add a map to map a.iContactforSF__Contact__c -> cont.Owner.ContactID in there so you can match them up again.
As for testing, it's hard to say without knowing your data model.
You'll have to manually create all the related records in accordance with the data model you have (a contact and a user at minimum) and then verify this trigger does what you want it to do. There's a great article here that should point you in the right direction:
https://developer.salesforce.com/page/An_Introduction_to_Apex_Code_Test_Methods
"You'll also have to add a map to map a.iContactforSF__Contact__c -> cont.Owner.ContactID in there so you can match them up again."
trigger iContactEmailAlert on iContactforSF__iContact_Message_Statistic__c ( Before Insert, Before Update ) {
set<id> OwnerIds;
set<ID> contactIDs;
For ( iContactforSF__iContact_Message_Statistic__c a : Trigger.New)
{
//Adding the contact into a set
contactIDs.Add ( a.iContactforSF__Contact__c) ;
}
For ( Contact cont : [Select ID, owner.ContactID from Contact where ID in :contactIDs])
{
//Adding the Owner's ID from contact into a set
OwnerIds.add(cont.Owner.ContactID);
}
//Getting related contact owner's email address
Map<id, User> conOwnerEmail = new Map<id, User>([Select Email From User Where ID IN:OwnerIds ]);
For ( iContactforSF__iContact_Message_Statistic__c a : Trigger.New)
{
//Populating the related contact's email address using Map functionality
a.ContactOwnerEmail__c = conOwnerEmail.get(a.iContactforSF__Contact__c.Owner.ContactId).Email ;
}
}
I think I'll be able to put a test code together with that link. Thanks for that.
a.ContactOwnerEmail__c = conOwnerEmail.get(a.iContactforSF__Contact__c.Owner.ContactId).Email;
So we need something were we can pass a.iContactforSF__Contact__c and end up with the related .Owner.ContactId
so in the .Owner.ContactId loop, we need to maintain the association with the a.iContactforSF__Contact__c. To do that we need to throw a map in there,
map<id, id> contactToOwneIDMap = new map<id,id>();
For ( Contact cont : [Select ID, owner.ContactID, Email from Contact where ID in :contactIDs])
{
//Adding the Owner's ID from contact into a set
OwnerIds.add(cont.Owner.ContactID);
contactToOwnerIDMap.put(cont.id, cont.owner.contactID);
}
Then we change our end goal so we can line everything up
a.ContactOwnerEmail__c = conOwnerEmail.get(contactToOwnerIDMap.get(a.iContactforSF__Contact__c)).Email;
Though really, we could simplify it by just getting the email as well in the contact query
map<id, string> contactToOwnerEmailMap = new map<id,string>();
For ( Contact cont : [Select ID, owner.ContactID, owner.Contact.Email from Contact where ID in :contactIDs])//when possible don't assign a separate variable to store the query then iterate through it. Putting the query directly into the loop saves you heap space so you are less likely to run into the memory governor limits.
{
//create a contactMap with the Owner 's email in it
contactToOwnerIDMap.put(cont.id, cont.owner.Contact.Email);
}
...
//cut out the other query since it's no longer needed
...
a.ContactOwnerEmail__c =contactToOwnerEmailMap.get(a.iContactforSF__Contact__c);
Though in reality, now that i think about it a bit more, chances are you don't need this code at all and could just turn ContactOwnerEmail__c into a formula field that does it.