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
Ruud Dirksen 4Ruud Dirksen 4 

getting ParentId in lightning:recordViewForm component

Hi,

I'm trying to recreate the standard Related Record component that we have available in lightning since it's not functioning properly for Person Accounts. The component should display information of the related Account when a user is working on a Case. I thought it would be a good idea to make a lightning:recordViewForm component and diplay all the fields as lightning:outputFields. 

Actually creating the layout shouldnt be a problem. I'm having trouble getting to the AccountId and placing it in the recordId attribute. My code so far:
<aura:component implements="flexipage:availableForAllPageTypes, force:hasRecordId" access="global">

    <lightning:recordViewForm recordId="???" objectApiName="Account">
        <div class="slds-box slds-theme_default">
            <lightning:outputField fieldName="Name" />
            <lightning:outputField fieldName="Phone"/>
            <lightning:outputField fieldName="PersonEmail" />
            <lightning:outputField fieldName="PersonBirthdate" />
        </div>
    </lightning:recordViewForm>
    
</aura:component>
I guess I should use force:recordData somehow but don't know enough about lightning components to get this to work. Help is much appriciated!

Thanks!

 
Best Answer chosen by Ruud Dirksen 4
Suraj TripathiSuraj Tripathi

Hi Ruud, 

As your requirement was to show Account details to be visible on the Case object for that I have made some code Changes. I have created :
1. Apex Class - Name - > RecordTestClass  (I have used this for querying the fields of Account from Case Object ).
2. Apex Controller - Name - > RecordIdTestController ( Used to  pass the data to helper.)
3. Apex Helper  - > RecordIdTestHelper (Use to call the apex class and store in some object).

Below is the code for the same.

Apex Component:

<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global" 
                controller="RecordTestClass">
    <aura:attribute name="recordId" type="Id"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>  
    <aura:attribute name="CaseObject" type="Object"/>
    <aura:attribute name="CaseObjectList" type="Object[]"/>    
     
     <h1>Record ID Test :</h1> 
     <div id="Content-Table">
        <table class="slds-table slds-table_bordered slds-table_cell-buffer">
            <thead>
            <tr class="slds-text-title_caps">
                <th scope="col">
                    <div class="slds-truncate" title="Account Name">Account Name</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Account Name">Contact LastName</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Close Date">Contact Phone</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Stage">Contact Email</div>
                </th>
            </tr>
            </thead>
            <tbody>
            <aura:iteration items="{!v.CaseObjectList}" var="case">
            <tr>
                 <td data-label="AccountName">
                    <div class="slds-truncate" title="{!case.Account.Name}">
                        <a href="{!'/'+case.AccountId}" target="_blank">
                                {!case.Account.Name}
                        </a>
                    </div>
                </td>
                <td data-label="Last Name">
                    <div class="slds-truncate" title="{!case.Contact.LastName}">
                        <a href="{!'/'+case.Id}" target="_blank">
                                {!case.Contact.LastName}
                        </a>
                    </div>
                </td>
               <td data-label="Phone">
                    <div class="slds-truncate" title="{!case.ContactPhone}">{!case.ContactPhone}</div>
                </td>
                <td data-label="Email">
                    <div class="slds-truncate" title="{!case.ContactEmail}">{!case.ContactEmail}</div>
                </td>
            </tr>
            </aura:iteration>
            </tbody>
        </table>
    </div>
</aura:component>


Apex Controller :
({
    doInit : function(c,e,h) {
        h.doInit_Helper(c,e,h) 

    }, 
})

Apex Helper : 
({
    doInit_Helper : function(c,e,h) {
        var id = c.get("v.recordId");
        console.log('id is-->>' + id);
        var action = c.get("c.getcase_Apex");
        action.setParams({
            "caseid": id
        });
        action.setCallback(this, function (r) { 
            if (r.getState() === 'SUCCESS') {
                console.log('state' + r.getState());
                var storedResponse = r.getReturnValue();
                console.log('storedResponse-->>' + JSON.stringify(storedResponse));
                if (storedResponse !== null) {
                    var newObjList = [];
                    for (var i = 0; i < storedResponse.length; i++) {
                        var obj = storedResponse[i];
                        var newObj = {};
                        for (var key in obj) {
                            if (obj.hasOwnProperty(key)) {
                                var keyList = key.split('__');
                                var newKey = '';
                                if (keyList.length > 2) {
                                    newKey = keyList[1].concat('__' + keyList[2]);
                                } else {
                                    newKey = key;
                                }
                                newObj[newKey] = obj[key];
                            }
                        }
                        c.set("v.CaseObject", newObj);
                        newObjList.push(newObj);
                    }
                    console.log('newObjList --> ' + JSON.stringify(newObjList));
                    c.set("v.CaseObjectList", newObjList);
                    console.log('CaseObjectList --> ' + JSON.stringify(c.get("v.CaseObjectList")));
                }
            } else {
                console.log('ERROR'); 
                console.log(r.getError());
            }
        });
        $A.enqueueAction(action);
    },
})


Apex Class :
public class RecordTestClass {
    @AuraEnabled
    public static List<Case> getcase_Apex (String caseid) {
        system.debug('In Apex class with Case id-->'+caseid); 
        if (caseid != null) {
            List<Case> caseList = new List<Case>();
            caseList = [SELECT  AccountId,Account.Name , ContactId, Contact.LastName,ContactPhone ,ContactEmail  FROM Case  WHERE id = :caseid ];
            if (caseList.size() > 0) {
                    return caseList;
            }
            system.debug('caseList--->'+caseList);
        } 
        return null;
    }
}    

Screenshot :
User-added image

Hope it helps you. It is working fine in my Org. Mark this answer best if it resolves your query.


Regards,
Suraj​

All Answers

Suraj TripathiSuraj Tripathi

Hi Ruud ,

Just create a attribute with name as 'recordId' and in lightning recordViewForm use that attribute. So your code will look like this :

<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global">
    <aura:attribute name="recordId" type="Id"/>
    <h1>Record ID Test :</h1>
     <lightning:recordViewForm recordId="{!v.recordId}" objectApiName="Account">
        <div class="slds-box slds-theme_default">
            <lightning:outputField fieldName="Name" />
            <lightning:outputField fieldName="Phone"/>
            <lightning:outputField fieldName="PersonEmail" />
            <lightning:outputField fieldName="PersonBirthdate" />
        </div>
    </lightning:recordViewForm>
</aura:component>  

Screenshot :
User-added image

Hope it helps you. It is working fine in my Org. Mark this answer best if it resolves your query.


Regards,
Suraj

Ruud Dirksen 4Ruud Dirksen 4
Hi Suraj,

Thanks for the help! If I place my component on an Account layout it works just like your screenshot. My use case requires the Account details to be visible on the Case object however. See example below (left). This example is a standard Related Record component, due to constant 'technical stuff' popups we want to replace this with a custom component. 

User-added image

So now my code looks like:
<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global">
    
    <aura:attribute name="recordId" type="Id"/>

    <lightning:recordViewForm recordId="{!v.recordId}" objectApiName="Account">
        <div class="slds-box slds-theme_default">
            <lightning:outputField fieldName="Name" />
            <lightning:outputField fieldName="Phone"/>
            <lightning:outputField fieldName="PersonEmail" />
            <lightning:outputField fieldName="PersonBirthdate" />
        </div>
    </lightning:recordViewForm>
    
</aura:component>
Where recordId is the Id of the current Case. Any idea how we can get to the Case.AccountId from here? 

Thanks!

Regards,

Ruud 

 
Suraj TripathiSuraj Tripathi

Hi Ruud, 

As your requirement was to show Account details to be visible on the Case object for that I have made some code Changes. I have created :
1. Apex Class - Name - > RecordTestClass  (I have used this for querying the fields of Account from Case Object ).
2. Apex Controller - Name - > RecordIdTestController ( Used to  pass the data to helper.)
3. Apex Helper  - > RecordIdTestHelper (Use to call the apex class and store in some object).

Below is the code for the same.

Apex Component:

<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global" 
                controller="RecordTestClass">
    <aura:attribute name="recordId" type="Id"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>  
    <aura:attribute name="CaseObject" type="Object"/>
    <aura:attribute name="CaseObjectList" type="Object[]"/>    
     
     <h1>Record ID Test :</h1> 
     <div id="Content-Table">
        <table class="slds-table slds-table_bordered slds-table_cell-buffer">
            <thead>
            <tr class="slds-text-title_caps">
                <th scope="col">
                    <div class="slds-truncate" title="Account Name">Account Name</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Account Name">Contact LastName</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Close Date">Contact Phone</div>
                </th>
                <th scope="col">
                    <div class="slds-truncate" title="Stage">Contact Email</div>
                </th>
            </tr>
            </thead>
            <tbody>
            <aura:iteration items="{!v.CaseObjectList}" var="case">
            <tr>
                 <td data-label="AccountName">
                    <div class="slds-truncate" title="{!case.Account.Name}">
                        <a href="{!'/'+case.AccountId}" target="_blank">
                                {!case.Account.Name}
                        </a>
                    </div>
                </td>
                <td data-label="Last Name">
                    <div class="slds-truncate" title="{!case.Contact.LastName}">
                        <a href="{!'/'+case.Id}" target="_blank">
                                {!case.Contact.LastName}
                        </a>
                    </div>
                </td>
               <td data-label="Phone">
                    <div class="slds-truncate" title="{!case.ContactPhone}">{!case.ContactPhone}</div>
                </td>
                <td data-label="Email">
                    <div class="slds-truncate" title="{!case.ContactEmail}">{!case.ContactEmail}</div>
                </td>
            </tr>
            </aura:iteration>
            </tbody>
        </table>
    </div>
</aura:component>


Apex Controller :
({
    doInit : function(c,e,h) {
        h.doInit_Helper(c,e,h) 

    }, 
})

Apex Helper : 
({
    doInit_Helper : function(c,e,h) {
        var id = c.get("v.recordId");
        console.log('id is-->>' + id);
        var action = c.get("c.getcase_Apex");
        action.setParams({
            "caseid": id
        });
        action.setCallback(this, function (r) { 
            if (r.getState() === 'SUCCESS') {
                console.log('state' + r.getState());
                var storedResponse = r.getReturnValue();
                console.log('storedResponse-->>' + JSON.stringify(storedResponse));
                if (storedResponse !== null) {
                    var newObjList = [];
                    for (var i = 0; i < storedResponse.length; i++) {
                        var obj = storedResponse[i];
                        var newObj = {};
                        for (var key in obj) {
                            if (obj.hasOwnProperty(key)) {
                                var keyList = key.split('__');
                                var newKey = '';
                                if (keyList.length > 2) {
                                    newKey = keyList[1].concat('__' + keyList[2]);
                                } else {
                                    newKey = key;
                                }
                                newObj[newKey] = obj[key];
                            }
                        }
                        c.set("v.CaseObject", newObj);
                        newObjList.push(newObj);
                    }
                    console.log('newObjList --> ' + JSON.stringify(newObjList));
                    c.set("v.CaseObjectList", newObjList);
                    console.log('CaseObjectList --> ' + JSON.stringify(c.get("v.CaseObjectList")));
                }
            } else {
                console.log('ERROR'); 
                console.log(r.getError());
            }
        });
        $A.enqueueAction(action);
    },
})


Apex Class :
public class RecordTestClass {
    @AuraEnabled
    public static List<Case> getcase_Apex (String caseid) {
        system.debug('In Apex class with Case id-->'+caseid); 
        if (caseid != null) {
            List<Case> caseList = new List<Case>();
            caseList = [SELECT  AccountId,Account.Name , ContactId, Contact.LastName,ContactPhone ,ContactEmail  FROM Case  WHERE id = :caseid ];
            if (caseList.size() > 0) {
                    return caseList;
            }
            system.debug('caseList--->'+caseList);
        } 
        return null;
    }
}    

Screenshot :
User-added image

Hope it helps you. It is working fine in my Org. Mark this answer best if it resolves your query.


Regards,
Suraj​

This was selected as the best answer
Ruud Dirksen 4Ruud Dirksen 4
Hi Suraj,

Thanks for all your help! Based on your example I noticed what I was missing in one of my earlier attempts (missing attributes). Even though your version also works for me I was really hoping to manage without writing any controllers. I came across this trailhead that explains this in detail:

https://trailhead.salesforce.com/en/modules/lightning_data_service/units/lightning_data_service_manipulate_records

My code now looks like:
 
<aura:component implements="flexipage:availableForAllPageTypes,force:hasRecordId" access="global">
    
    <aura:attribute name="recordId" type="Id"/>
    <aura:attribute name="record" type="Object"
		description="The record object to be displayed"/>
	<aura:attribute name="simpleRecord" type="Object"
    	description="A simplified view record object to be displayed"/>
    <aura:attribute name="recordError" type="String"
    	description="An error message bound to force:recordData"/>
    
    <force:recordData aura:id="record"
    	layoutType="FULL"
		recordId="{!v.recordId}"
		targetError="{!v.recordError}"
		targetRecord="{!v.record}"
		targetFields ="{!v.simpleRecord}"
		mode="VIEW"/>                      

    <lightning:recordViewForm recordId="{!v.simpleRecord.AccountId}" objectApiName="Account">
        <div class="slds-box slds-theme_default">
            <lightning:outputField fieldName="Name" />
            <lightning:outputField fieldName="Phone"/>
            <lightning:outputField fieldName="PersonEmail" />
            <lightning:outputField fieldName="PersonBirthdate" />
        </div>
    </lightning:recordViewForm>
    
</aura:component>


So no controller needed!  

Regards,
Ruud

Suraj TripathiSuraj Tripathi
Thank you, Ruud for selecting my answer as best. It's my pleasure to help you.
Saurabh Bisht 8Saurabh Bisht 8
I was fetching parentId through vfPage before the spring 18 updates, and it was working fine. But i'm not getting it now.... I was using this code..
VF Page:
<apex:page standardController="Custom_Object">
<div id="lightningCmp"/>
<apex:includeLightning />

<script>
        var b_id = '{!$CurrentPage.parameters.CF00N5D000000TJgE_lkid}';
        console.log('@@@@@@'+b_id);
        $Lightning.use("c:TestApp", function() {
            $Lightning.createComponent(
                "c:TestCmp",
                {"parentId":b_id},
                "lightningCmp",
                function(cmp) {
                    console.log("##");
                    //console.log(cmp);
                });
            });
       
</script>
</apex:page>

TestCmp:
<aura:attribute name="parentId" type="String"/>

TestController:
var pid = cmp,get("v.parentId");
alert(pid);

Not getting pid ...

Can anyone help???
Pedro Loaiza 5Pedro Loaiza 5
Hello,

Trying to do something similar. I used the code for the component without the controller and although it displays the fields for the account, it throws and error:

Action failed: lightning:recordViewForm$controller$handleRecordIdChange [Cannot read property 'getList' of null]

Any ideas?

Thanks,

Pedro
Sharda Kumari 9Sharda Kumari 9
Hi @pedro Loaiza 5
I am getting the same error. How did you resolve this?
Appreciate any help!