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
Petteri KoivunenPetteri Koivunen 

Differences between classic and lightning when triggering create opportunity?

I'm trying to get OpportunityContactRoleId while creating new Opportunity to Contact.

If I'm using Salesforce Classic, the following example works fine.
But if I switch to Lightning, I got error "createupdate_opportunity_trigger: execution of AfterInsert caused by: System.QueryException: List has no rows for assignment to SObject Trigger.createupdate_opportunity_trigger: line 7, column 1"

So, this means that OpportunityContactRole is not linked with Opportunity. Why this works if I use Classic? How do I get ContactId when using Lightning?
 
trigger createupdate_opportunity_trigger on Opportunity (after insert, after update) 
{
    for(Opportunity o:Trigger.new) 
    {
        if (o.id != null)
        {
            OpportunityContactRole contactRole = [select ContactId from OpportunityContactRole where IsPrimary = true and OpportunityId = :o.Id];
            if (contactRole != null)
            {
                System.debug('Found: ' + contactRole.ContactID);
            }
        }
    }
}

 
Gokula KrishnanGokula Krishnan
Hi Petteri,

OpportunityContactRole is child for Opportunity, After Opportunity Created only OpportunityContactRole will be created. So, in your trigger no of after Insert operation. And also its not good  practise to use Query inside the loop.

Try this,
 
trigger createupdate_opportunity_trigger on Opportunity ( after update) 
{
	List<id> Oppid = new List<id>();
    for(Opportunity o:Trigger.new) 
    {
        if (o.id != null)
		Oppid.add(o.id);
    }
	
	if(Oppid.size()>0){
		For(OpportunityContactRole contactRole : [select ContactId from OpportunityContactRole where IsPrimary = true and OpportunityId = :Oppid]){  
				if (contactRole != null)
				{
					System.debug('Found: ' + contactRole.ContactID);
				}
		}
	}
}

Thanks!!!

If it helps you, please mark is as best answer, so it will be helpful for other developers.
Waqar Hussain SFWaqar Hussain SF
Opportunity Contact roles are available in lightning. You can see the below documetation..

However you will need to modify your code to work for the condition, if there is not promiary contact on opoortunity and also should be bulkify.
 
trigger createupdate_opportunity_trigger on Opportunity (after insert, after update) 
{	
	list<OpportunityContactRole> contactRoles = [select OpportunityId, ContactId from OpportunityContactRole where IsPrimary = true and OpportunityId IN = :trigger.newMap.keySet()];
	
	Map<Id, OpportunityContactRole> OpportunityContactRoleMap = new Map<Id, OpportunityContactRole>();
	for(OpportunityContactRole opcr: contactRoles){
	OpportunityContactRoleMap.put(opcr.OpportunityId, opcr);
	}
    for(Opportunity o:Trigger.new) 
    {
        if (o.id != null)
        {
			OpportunityContactRole contactRole = OpportunityContactRoleMap.get(o.Id);
            if (contactRole != null)
            {
                System.debug('Found: ' + contactRole.ContactID);
            }
        }
    }
}

Let me know If you have any concern. 
Petteri KoivunenPetteri Koivunen

Thank you for both,
Unfortunately solutions didn't work.

First solution:
'After update' triggers only when updating opportunity. If I update opportunity, it triggers fine. But problem is, when creating a new Opportunity to contact, it did not triggered. If I add 'after insert', it works with classic but with lightning OpportunityContactRole is not found.


Second solution:
This works with classic but if I switch to Lightning it did not. OpportunityContactRole is not found.

Is the opportunitycontactrole created asynchronously in Lightning? I mean that link between opportunity and contact does not exists while creating/triggering Opportunity?