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
Petros MoustridesPetros Moustrides 

Can't retrieve a related parentid when overriding standard actions with a lightning components

I have a lightning component that implements lightning:actionOverride how do I get the recordId of the parent when the action is triggered from a related list?
Mustafa JhabuawalaMustafa Jhabuawala
Hi Petros,

To get the recordID you need to implement interfacte force:hasRecordId along with lightning:actionOverride.

force:hasRecordId - This enables the component to be assigned the ID of the current record.

You can get the recordId when the component is loaded in the init method and can perform the further logic.

Below is the sample code - 

For example -
smapleComponent.cmp
<aura:component implements="lightning:actionOverride,force:hasRecordId">
    <!-- Your code goes here -->
    <aura:handler name="init" value="{!this}" action="{!c.onInit}"></aura:handler>
</aura:component>
sampleComponentController.js
({
   onInit : function(component,event,helper){
        var recordId = component.get("v.recordId");//LINE 4
        alert(recordId);
   }
})
Remember - Whenever you implement force:hasRecordId an attribute is added internally named as recordId which you can access in the controller or component. In the above example it is accessed in the controller JS 'LINE 4'.

Helpful links - 
lightning:actionOverride (https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/ref_interfaces_lightning_actionoverride.htm?search_text=lightning:actionOverride)
force:hasRecordId (https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/ref_interfaces_force_hasrecordid.htm?search_text=force:hasRecordId)

Note - Kindly mark this answer as best answer if this helped you, so that other's can also get benefit from it.

Thanks,
Mustafa Jhabuawala
Technical Lead at Zen4orce (http://www.zen4orce.com)

 
Petros MoustridesPetros Moustrides
I have already tried this but I am finding when overriding new the value of recordid is null when The action is triggered from a related list I can not retrieve the related records id. Ie new from contact related list on account  I can't get the accountid.
Mustafa JhabuawalaMustafa Jhabuawala
Can you share your code and screen shots, that would be helpful to resolve the issue.
Sukanya BanekarSukanya Banekar
Hi Petros,

As per my understanding you need to pass the values to the standard field id's in the url i.e Salesforce URL hacking. 
OR
you can get the Id of the parent as below 
1. get the URL of current page when you click on overriden action 
string strURL= string.valueof(ApexPages.currentPage());
string strId='';
if(strURL.contains('=001')){          // this is id for account (you can get first 3 number from id of you parent record) 
    strId= strURL.substringBetween('=001','&'); // find parent id from string url  
    strParentId = ('001'+strId).trim(); // concatinate with 3 digits
}


I hope this helps you to get ParentId, let me know if you need additional help.

Thanks,
Sukanya Banekar
Salesforce Developer
http://www.zen4orce.com
 
Mustafa JhabuawalaMustafa Jhabuawala
Hi Petros,

I found your question interesting and challenging one.

Me and Sukanya have tried multiple possible ways to acheieve the functionality as you have mentioned.

Following are the findings - 
1. I noticed that when you override the New action with a lightning component, and when you click on that 'New' button it navigates to a different URL, so in this case we won't be able to use URL hacking to get the parent Id from URL.
2. Instead of overriding the standard new action, you can create a new action button. Please refer below screen shot
User-added image
I know its a quite different approach but this is how you can achieve this. So clicking on the new action button you will get the details in recordID for which you have to implmenet force:hasRecordId in your custom component.

So bascially the alternative approach would be to use action button.

Note - Kindly mark this answer as a best answer if this helped you, so that other's can also get benefit from it.

Thanks,
Mustafa Jhabuawala
Techincal Lead at Zen4orce (http://www.zen4orce.com)
LinvioIncLinvioInc

If developers are going to override the "New" action, they will more than likely need to access the parent Id.  Without it you can't establish the context of the action and attach your new record to parent.  I've inspected the value provider and referring URL from inside the lightning component and the source (or parent) record ID doesn't seem to be set anywhere.   Any other ideas/suggestions?

 

Dileep Singhal 18Dileep Singhal 18
Hello All,
The same is happening with me. As created a new object which is in relationship of account where account is master object. New button of child obeject override with a lightning component. Code is given below

<aura:component implements="force:hasRecordId,lightning:actionOverride" controller="Customer_Issue_New_Record_cls" access="global">
    <aura:attribute name="newIssueObject" type="xCustomer_Issue__c" default="{ 'sobjectType': 'xCustomer_Issue__c' }"/>
    <aura:attribute name="recordId" type="String" default=""/>
    <aura:handler name="init" value="{!this}" action="{!c.initSetup}" />
</aura:component>

({
    initSetup : function(component, event, helper) {
        console.log('------accountid-------'+component.get("v.recordId"));
    }
})


Thank you
Dileep 
Michael PaisnerMichael Paisner
Has anyone been able to retrieve the parent recordId when the quick action overrides the standard New button on a related list?

Note that I can retrieve the recordId when the Lightning Component is launched from a Global Quick Action.  My question is specific to the situation where the Quick Action replaces the New button on the related list.  In this situation, recordId comes up as undefined.

Thanks,
Mike
Jeffrey KoJeffrey Ko
Hello - I was wondering of anyone found a solution to the above problem?  I have the same issue, where I am overriding the New button with Lightning component, and when I click "New" on the related list, the Lightning component needs to get the parent ID in order to set it ... if anyone solved this, please let me know. :)
Rohan Kumbhar 4Rohan Kumbhar 4
Anyone got this working? I have same requirement to be implemented where I need to override New button to prepopulate some fields which I have acommplished buy lightening component. Due to overriding the parent Id is not getting populated from related list. Has anyone able to get parent ID? Thank you in advance!!
Jeffrey KoJeffrey Ko
I did the following hack/workaround to get it to work for me:
  • I override the standard New button to point to the Lightning component
  • I created another custom New button with a Display Type = "List Button" (this button is then added to the page layout to replace the standard "New" button in the Related List).  This button is a URL type.  The URL points to the URL of the new child record page in Lightning, with a URL parameter to get the parent ID.
  • The Lightning component then retrieves the URL parameter to get the parent ID.

Good luck!  :)
Reshma TestReshma Test
Hi Jeffrey,
I created list button with url type. But didn't get child record page in Lightning. Do you have an example url to populate here.

Thanks
Jeffrey KoJeffrey Ko
For me, the URL to the custom "New" page for the Child object was "/lightning/o/CHILDOBJ__c/new?clientId={!Account.Id}".  
JegadheesanJegadheesan
We can achieve it through intermediate VF page by using the below code. The below VF page using the standardcontroller for Contact and opening our intermediate component using projectOneNavigator javascript
<apex:page standardController="Contact" lightningStylesheets="true">
  <script src="../../soap/ajax/37.0/connection.js" type="text/javascript"></script>
    <script >
        
        if(SfdcApp.projectOneNavigator) {
           SfdcApp.projectOneNavigator.fireContainerEvent("force:navigateToComponent", {componentDef: 'c:NewRecordIntermediate',
                   componentAttributes: {
                     sObjectName: "{!$CurrentPage.parameters.ent}",
                     recordTypeId: "{!$CurrentPage.parameters.RecordType}",
                     accId: "{!$CurrentPage.parameters.accid}"
                },
                resetHistory: false
                });      
        }
    </script> 
</apex:page>
NewRecordIntermediate - Lightning component to create contact. 
If we click New from Contact tab it will just assign RecordTypeId if record type available. 
If we click New from Related List under Account we will get accid from url. we can pass this to Lightning component attributes.

Let me know if you have any queries.

 
Zachary Alexander 22Zachary Alexander 22
Using Lightning-Out through Visualforce seems to work. Example below will populate the lightning component's "parentId" attribute. Seems bizarre that this isn't basic functionality...
 
<!-- This VF page hosts a Lightning Component. -->
<apex:page standardcontroller="Patient_Incident_Accident__c">
	
  <!-- Load Lightning dependencies -->
  <apex:includeLightning />

    <div class="slds">
        <!-- Target div for the Lightning component -->
        <div id="customObjectEdit"></div>
    </div> 
    
    <apex:pageBlock >
    <div class="slds-scope">
        <apex:form >
            <div class="slds-form slds-form_stacked">
                <apex:outputPanel >
                    <apex:commandButton action="{!cancel}" value="Return" styleClass="slds-button slds-button_destructive"/>
                </apex:outputPanel>
            </div>
        </apex:form>
    </div>
    </apex:pageBlock>
    
  <script>
    var varRecordId = '{!Patient_Incident_Accident__c.Id}';
    var varParentId = '{!Patient_Incident_Accident__c.Patient_Name__c}';

    $Lightning.use("c:HB_LApp_Patient_Incident_Form", function() {
      var attributes = {
        recordId: varRecordId, parentId: varParentId
      };

      var targetElementId = 'customObjectEdit';

      $Lightning.createComponent('c:HB_L_Patient_Incident_Form', attributes, targetElementId,
        function(cmp) {
          // At this point the component has been created and loaded
      });
    });
  </script>
</apex:page>

 
Pascal Le ClechPascal Le Clech
Here is the solution :

in component
<aura:component implements="lightning:actionOverride,flexipage:availableForRecordHome,force:hasRecordId" access="global" >
    <aura:handler name="init" value="this" action="{!c.doInit}"/>
    <aura:attribute name="parentRecordId" type="String" />
    <p>{!v.parentRecordId}</p>
</aura:component>
in controller :
({
	doInit : function(component, event, helper) {
        var value = helper.getParameterByName(component , event, 'inContextOfRef');
        var context = JSON.parse(window.atob(value));
        component.set("v.parentRecordId", context.attributes.recordId);
	}
})

in helper :
({
    getParameterByName: function(component, event, name) {
        name = name.replace(/[\[\]]/g, "\\$&");
        var url = window.location.href;
        var regex = new RegExp("[?&]" + name + "(=1\.([^&#]*)|&|#|$)");
        var results = regex.exec(url);
        if (!results) return null;
        if (!results[2]) return '';
        return decodeURIComponent(results[2].replace(/\+/g, " "));
    }
})

You're welcome ! 😉 


 
VarunCVarunC
This ia vry good workaround, but it fails in Salesforce1 App when override is used for Mobile as well :-|
Saranyan V NarayananSaranyan V Narayanan
Can you confirm its a standard Action being passed or a Custom Button with URL as formula?

If recordID is null you can get 


 if ( response.recordId ==null)
            {
                var ParentURL = response.pageReference.state.ws ;// or url parameter of response as response.url
                //var context = response.pageReference.state.inContextOfRef ;
               
                    cmp.set("v.relatedURL",ParentURL);
                    //split the parentURL and get corresponding value for example
                    //cmp.set("v.ParentSObjectType",ParentURL.split("/")[3]);
                   
                    //cmp.set("v.ParentSObjectId",ParentURL.split("001")[0]);
               }

Again I just tried this and it worked for me, your specific case I might need relevant details to answer better
VarunCVarunC
This original post in my understanding is not related to a custom button. The behavior is observed when you've a Lightning Component and you ahve used it to Override a Standard Action (such as New button on the object). Now, when you're clicking the New button from a Related List of that object then the Lightning Component is activated BUT it looses the context of the record it was initiated from.

This means, as a developer you can't know the origin of the request. For example, you may have a Lightning Component override for New Contact. And now, if you try to create a New Contact from Account record, from contacts related list, you're Lightning Component have no way to read the Account ID and populate it when New Contact interface is loaded in your custom component.

As for your code, can you guide me, where does your "response" variable coming from? Ina  lightning component, if we need record id, I think we read it by component.get("v.recordId").
Saranyan V NarayananSaranyan V Narayanan
Hi , This comes from console app workspace api response to get tabname. ({ 02 closeFocusedTab : function(component, event, helper) { 03 var workspaceAPI = component.find("workspace"); 04 workspaceAPI.getFocusedTabInfo().then(function(response) { 05 var focusedTabId = response.tabId; Are you using console app in lex? Regards, Saranyan Narayanan Salesforce Architect Wilco Source Skype:saranyann@wilcosource.com 9963028094
VarunCVarunC
No, regular Lightning Navigation.
Saranyan V NarayananSaranyan V Narayanan
Lightning Experience you mean or you have a lightning app.
I was able to do it in a Lightning experience with the console app. with the code I gave , could you give your component/app hierarchy as a sample and I can verify and let you know , Also are you checking recordid in init, if so let me know .
Saranyan V NarayananSaranyan V Narayanan
One more alternative I can think of is Create a Button(Custom button)  with a ws parameter which passes the related Object Id
It is the only parameter which will work and you can get the param
For example 
ws=/lightning/r/Account/001V000000YYPduIAH/view ( using url formula) 

{!URLFOR( $Action.Case.NewCase , null,[ws=/lightning/r/Account/'+Case.AccountId'+ '/view' ]) }

get the param ws from window.location.href and then parse the url for the id.

Regards
Saranyan Narayanan



 
VarunCVarunC
https://salesforce.stackexchange.com/questions/232223/lightning-component-as-actionoverride-for-standrad-new-button-do-not-prepopulat

I've full code here, you can try it with as a Lightning Component and override Contact New button, and then try creating a New Contact from Account's Contact Related List. 

Creating custom button is not valid workaround, One cannot replace all the places where New button appears with a custom button.

And it is an inconsistent behavior since the parent record id is passed to lightning component override if we have a Record Type on the object. so if I create Record Types on Contact objectg I can then have Account Id available in URL when creating the New Contact using same code for lightning component.
 
Komal MehtaKomal Mehta
There are multiple approches mentioned in the above thread. Can anyone explain how to overcome this problem?
Also, if we create a new custom quick action then will it be possible to replace it with standard New button in related list of Parent object?
ProtyushCProtyushC
The best possible workaround for the issue is:

component:
-------------------
<aura:component implements="flexipage:availableForRecordHome,flexipage:availableForAllPageTypes,force:hasRecordId,lightning:actionOverride,lightning:isUrlAddressable">
    <aura:attribute name="recordId" type="Id"/>
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
</aura:component>
controller:
-------------------
({
    doInit : function(component, event, helper) {
        var pageRef = component.get("v.pageReference");
        var state = pageRef.state; // state holds any query params
        var base64Context = state.inContextOfRef;
		/*
			*For some reason, the string starts with "1.", if somebody knows why,
			*this solution could be better generalized.
		*/
         if (base64Context.startsWith("1\.")) {
            base64Context = base64Context.substring(2);
        }
        var addressableContext = JSON.parse(window.atob(base64Context));
        component.set("v.recordId", addressableContext.attributes.recordId);
})
vamshi kothakapu 9vamshi kothakapu 9
var fullURL = window.location.href;
Create a quickaction for the component and accessing the url from init function of that component is one line code.
The above code gives u the full url from that url we can get Id of the parent record.
If it works mark my answer as Best.
vamshi kothakapu 9vamshi kothakapu 9
<aura:component implements="flexipage:availableForRecordHome,flexipage:availableForAllPageTypes,force:hasRecordId,lightning:actionOverride,lightning:isUrlAddressable">     <aura:attribute name="recordId" type="Id"/>     <aura:handler name="init" value="{!this}" action="{!c.doInit}"/> </aura:component>
farukh sk hdfarukh sk hd
The main issue in overriding the button on related list is to get the parent record id but i believe instead of overriding the button we can create the custom related list component which would be exactly similar to standard related list and when we will be going to place this on record detail page of parent we can get the id of parent. I have implemented this you can have a look. https://www.sfdc-lightning.com/2019/08/custom-related-list-lightning.html

 
kira lkira l
We have been using @ProtyushC's solution and it's working as expected for desktop browsers. However, it doesn't work for mobile apps and browsers. Anyone here was able to resolve this for mobile as well? Thank you
RUMELI BANERJEERUMELI BANERJEE
It is not working in Salesforce 1 Mobile App.
Kapil BatraKapil Batra
Hello, we can get the parent Id in Salesforce 1 Mobile App also by doing some modification in the code.
Please check below blog post for reference : 

https://www.salesforcebolt.com/2020/04/get-parent-id-salesforce1-Lightning-Component.html
Emily Johnson 23Emily Johnson 23
I'm using @Pascal's approach defined above. However, when user clicks the "Save & New" button after creating a record, rather than the "New" button, I receive the following error: 

"Uncaught Action failed: c:NewQuotePrepopulated$controller$doInit [Unexpected token ž in JSON at position 0]
Callback failed: serviceComponent://ui.force.components.controllers.createRecordTypeChecker.CreateRecordTypeCheckerController/ACTION$doRecordTypeCheck"

Has anyone else encountered this error? If so, how did you resolve? Thanks for your help!
Rahul Kumar DeyRahul Kumar Dey
Hi Emily,

Got the same error after saving the record using @Pascal's solution. Have you found any solution/ workaround? please share...

Thanks,
Rahul:)
Irshaad Jaunbocus 9Irshaad Jaunbocus 9
Hi Emily and Rahul,

Did you come up with any solution for the Save and New button ? I'm stuck on same.

Thanks,
IJ