I have a VF page that is supposed to pull the contact role information from the opportunity page. The code works on the opportunity page, but I need to add it to a related object (custom object). The related object has a lookup field (Parent_Opportunity__c).

VF (Updated):

<apex:page standardController="Parent_Opportunity__c"

    <apex:pageBlock title="Opportunity Contact Roles" mode="edit">
        <apex:pageBlockTable value="{!Parent_Opportunity__c.Opportunity__r.ContactRoles}" var="ContactRole">
            <apex:column headerValue="Name" value="{!Parent_Opportunity__c.Opportunity__r.ContactRole.Contact.Name}"/>
            <apex:column headerValue="Phone" value="{!Parent_Opportunity__c.Opportunity__r.ContactRole.Contact.Phone}"/>
            <apex:column headerValue="Other Phone" value="{!Parent_Opportunity__c.Opportunity__r.ContactRole.Contact.OtherPhone}"/>
            <apex:column headerValue="Email" value="{!Parent_Opportunity__c.Opportunity__r.ContactRole.Contact.Email}"/>
            <apex:column headerValue="Role" value="{!Parent_Opportunity__c.Opportunity__r.ContactRole.Role}"/>


Error (Updated):

Error: Invalid field ContactRoles for SObject Opportunity

  • 1
    is Parent_Opportunity__c the API name of the custom object, as well? The standardController attribute takes the API name of the object. And then everywhere you have Opportunity__r, if the name of the field on the custom object is also Parent_Opportunity__c, you probably need to use Parent_Opportunity__r, unless you set the relationship name to be different from the field name. Jun 26, 2019 at 19:36
  • "Parent_Opportunity__c.Opportunity__r" worked, but getting the following error: "Error: Invalid field ContactRoles for SObject Opportunity"
    – user56320
    Jun 26, 2019 at 20:14
  • 2
    The correct reference to the child relationship would be Parent_Opportunity__c.Opportunity__r.OpportunityContactRoles. But when you use that, you're trying to use the Standard Controller, which doesn't support that up-then-down type of relationship. You'll need to query a list of the OppContactRoles in your controller extension and use that as the value of the pageBlockTable. Jun 26, 2019 at 20:22

1 Answer 1


You need to query for the Opportunity Contact Roles in your controller extension. So here's how the controller extension might look:


public class OpportunityContactRoleExtension {

    public List<OpportunityContactRole> contactRoles {get; set;}
    private final Parent_Opportunity__c parentOpp;
    // put any fields you need to use in the controller extension that 
    // don't appear on the VF page in this list
    private final List<String> fieldList = new List<String>{'Opportunity__c','Sample_Field__c'};

    public OpportunityContactRoleExtension(ApexPages.StandardController cntrl) {
        this.parentOpp = (Parent_Opportunity__c)cntrl.getRecord();
        this.contactRoles = [SELECT Id, Role, ContactId, Contact.Name, Contact.Phone, Contact.OtherPhone, Contact.Email
                            FROM OpportunityContactRole
                            WHERE OpportunityId = :parentOpp.Opportunity__c];

Then in your VF, the pageBlockTable opening tag becomes:

<apex:pageBlockTable value="{!contactRoles}" var="ContactRole">

and then strip everything before ContactRole from the values for all your <apex:column>s, eg: value="{!ContactRole.Contact.Name}"

  • 1
    Whoops! Parent_Opportunity__c. I fixed it, and the variable reference on the same line, above. It's casting the generic SObject that comes from StandardController.getRecord() to the specific object type you're working with. You'll also want to remove ,'Sample_Field__c' from fieldList unless you actually have such a field. It's just there to demonstrate the syntax for a multi-item list of strings. Jun 26, 2019 at 21:13
  • 1
    Based on what you said above, you shouldn't need to change the WHERE clause. If the object is Parent_Opportunity__c and the field on that object is Opportunity__c, it should work as-is. Jun 26, 2019 at 21:40
  • 1
    Add set; to the variable declaration in the controller extension. I think I took it out after testing, thinking it wasn't necessary if just displaying. Jun 26, 2019 at 22:12
  • sorry. I didn't follow that :(
    – user56320
    Jun 26, 2019 at 22:41
  • 1
    Look at the second line of code above. Where it used to say {get;} it now says {get; set;} . Make the same change. Jun 26, 2019 at 22:46

You must log in to answer this question.