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. – Thomas Taylor Jun 26 '19 at 19:36
  • "Parent_Opportunity__c.Opportunity__r" worked, but getting the following error: "Error: Invalid field ContactRoles for SObject Opportunity" – user56320 Jun 26 '19 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. – Thomas Taylor Jun 26 '19 at 20:22

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. – Thomas Taylor Jun 26 '19 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. – Thomas Taylor Jun 26 '19 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. – Thomas Taylor Jun 26 '19 at 22:12
  • sorry. I didn't follow that :( – user56320 Jun 26 '19 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. – Thomas Taylor Jun 26 '19 at 22:46

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy