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
Janis Davis 22Janis Davis 22 

Help with Error: Content cannot be displayed: SObject row was retrieved via SOQL without querying the requested field: Contact.Account

Since the Opportunity Contact Roles related list is not natively customizable, I took the advice of someone on the Communities and created a VisualForce page for the Opportunity Contact Roles to be able to pull the Mobile phone number field into the related list. That worked fine, except when I needed to add the Del link next to the Edit link so we can remove Contact from Opportunity Role that are no longer with the company and/or are no longer a Role in an Opportunity (screenshot below).

User-added image
Someone on the Community helped me with the VF code and also gave me some code to create a Controller. I followed the instructions, however I'm still getting the SObject row was retrieved via SOQL without querying the requested field: Contact.Account error. Pasted below is the code for both the VF page and the Controller. Can someone please tell me what I'm missing or doing wrong? Any help and/or advice on this will be most appreciated!

VF Page Code
<apex:page standardController="Opportunity" extensions="DeletePage" id="opfrm" >
    <apex:form id="form">  
        <apex:pageBlock title="Contact Roles">
            <apex:pageBlockTable value="{!opt}" var="ContactRole" id="pgblktab">
                <apex:column >
                    <apex:facet name="header">
                        Action
                    </apex:facet>
                    <a href="/p/opp/ContactRoleEditUi/e?oppid={!Opportunity.Id}&retURL=%2F{!Opportunity.Id}" target="_top">Edit</a>  |
                 <a href="javascript:if (window.confirm('Are you sure?')) Deleteopt('{!ContactRole.Id}');" style="font-weight:bold">Del</a>
                   </apex:column>
                <apex:column >
                    <apex:facet name="header"> Contact Name </apex:facet>
                    <a href="/{!ContactRole.Contact.Id}" target="_top">{!ContactRole.Contact.Name} </a>
                    </apex:column>
                <apex:column value="{!ContactRole.Contact.Account.Name}" headerValue="Account Name"/>
                <apex:column value="{!ContactRole.Contact.Email}" headerValue="Email"/>
                <apex:column value="{!ContactRole.Contact.Phone}" headerValue="Phone"/>
               <!-- <apex:column value="{!ContactRole.Role}" headerValue="Role"/>
<apex:column value="{!ContactRole.Contact.MobilePhone}" headerValue="Mobile"/>
            -->
<apex:column value="{!ContactRole.IsPrimary}" headerValue="Is Primary"/>
            </apex:pageBlockTable>  
            <apex:pageBlockButtons location="top">
                <input type="button" class="btn" value="New" onclick="javascript:window.open('/p/opp/ContactRoleEditUi/e?oppid={!Opportunity.Id}&retURL=%2F{!Opportunity.Id}');"/>
            </apex:pageBlockButtons>     
        </apex:pageBlock>  
          <apex:actionFunction action="{!Deleteopt}" name="Deleteopt" reRender="form">
         <apex:param name="OpportunityContactRoles" value="" assignTo="{!SelectedoptId}"/>
        </apex:actionFunction>       
    </apex:form>
</apex:page>

Controller Code
public with sharing class DeletePage {

   public List<OpportunityContactRole> opt{ get; set; }
  
 
   public string SelectedoptId { get; set; }
   public DeletePage(ApexPages.StandardController controller) {
    LoadData();
    }

   private void LoadData() {
       opt= [Select id,ContactId,IsPrimary,Contact.Name from OpportunityContactRole limit 20];
          }
  
   public pagereference Deleteopt()
   {
      // if for any reason we are missing the reference 
      if (SelectedoptId == null) {
      
         return null;
      }
     
      OpportunityContactRole  tobeDeleted = null;
      for(OpportunityContactRole a : opt)
       if (a.Id == SelectedoptId ) {
          tobeDeleted = a;
          System.debug('#############'+ a);
          break;
       }
      
      if (tobeDeleted != null) {
      Delete tobeDeleted;
      

      }
      LoadData();
      return null;
   } 
 
}

 

                    
 

 
FearNoneFearNone
Since you are accessing some of its fields in the visual page, add those to your query:        
Contact.Account.Name
Contact.Email
Contact.Phone
Role
Contact.MobilePhone
private void LoadData() {
       opt= [Select id,ContactId,IsPrimary,Contact.Name,Contact.Account.Name,Contact.Email,Contact.Phone,Role,Contact.MobilePhone, from OpportunityContactRole limit 20];
          }
        
if same kind of error still occurs, just add the missing field into your query.
Janis Davis 22Janis Davis 22
Thanks. I'm not sure I understand where to put this code in the VF page or Controller - just a novice at VF. Can you please give me some guidance on this?

Janis 
FearNoneFearNone
in the controller, LoadData() - function:
change the query to
private void LoadData() {
    opt= [Select id, ContactId,IsPrimary, Contact.Name, Contact.Account.Name, Contact.Email, Contact.Phone, Role, Contact.MobilePhone from OpportunityContactRole limit 20];
}