0

I am trying to override the standard button on the related list of Quote object using a lightning component [compA]. For some reason, the record id is undefined even if I have force:recordId and an attribute. I would need the recordId to prepopulate a field on my lightning component form and for redirection after the user hits save button. I created another lightning component that displays the record Id and placed it on the Quote record page just for testing and it successfully displays the id. Is there a way for me to get the record Id on my lightning component [compA]?

2 Answers 2

1

You'll have to pass the record Id to your aura component to have it.

Why?

hasRecordId

When your component is invoked in a record context in Lightning Experience or the Salesforce mobile app, the recordId is set to the ID of the record being viewed.

Clicking the "new" button on a related list opens a new page context (it'll be in its own tab) - in this case, it opens the Aura component away from the record (Quote). It no longer has the context of a record page and that is why you have no record Id.

Your test (LWC on Quote record page), which has a record context, and your situation (button on related list that opens new tab) are not the same conditions - hence, why you get different results.


You'd have to leverage a URL button (List Button) on the related list for this to work in that capacity. On the related list, you'd show your custom button and and hide the standard new button.

To do the URL part, you need to leverage IsUrlAddressable so you can use a link to call your Aura component with values - so you'll pass the record Id before it re-directs to your URL from the related list.

Your URL will be /lightning/cmp/c__componentname?c__quoteId={!Quote.Id}

<!-- 
make sure to implement it to be url addressable 
as well as available for all page types 
-->
<aura:component implements="lightning:isUrlAddressable,flexipage:availableForAllPageTypes">
<aura:attribute name="quoteId" type="String" />

<!-- Add an "init" handler to handle the first "v.pageReference" value -->
    <aura:handler name="init" value="{!this}" action="{!c.onPageReferenceChange}"/>
    <!-- Add a "change" handler to handle all changes to the "v.pageReference" value -->
    <aura:handler name="change" value="{!v.pageReference}" action="{!c.onPageReferenceChange}"/>
({
    onPageReferenceChange: function(cmp, evt, helper) {
        var myPageRef = cmp.get("v.pageReference");
        var quoteId = myPageRef.state.c__quoteId;
        cmp.set("v.quoteId", quoteId);
    }
})
4
  • Hi @Kris thank you for your answer! I tried the approach above but whenever my button is clicked, I am being redirected to a page with "This page isn't available in Salesforce Lightning Experience or mobile app". Though I am seeing in the url that it has the correct account Id. Any idea what could went wrong?
    – Charlie
    Commented Mar 24, 2022 at 14:22
  • Did you implement isUrlAddressable on the aura component? <aura:component implements="lightning:isUrlAddressable"> Commented Mar 24, 2022 at 14:24
  • Yes I included it as well
    – Charlie
    Commented Mar 24, 2022 at 14:43
  • apologies, I edited the answer. You just need to implement flexipage:availableForAllPageTypes as well. Commented Mar 24, 2022 at 15:14
0

I think I've found the solution for this issue. Prior solution posted works, in standard sales navigation. But, when navigating on Salesforce Console, the parameter myPageRef.state.c__quoteId contains the Id of the main tab record, not the Id of the record where the related list button was pressed. For instance: in console navigation, user opens an Account page, from this account, opens a Contact record (It opens as a subtab of account), and then, goes to create a Case in the contact related list. In this case, the parameter myPageRef.state.c__ would contain the Account Id instead of contact Id. In order to get the actual record Id, you need to do this: URL contains the needed data, all you have to do is to decode it:

initComponent : function(component, event, helper) {
    let recordId = component.get('v.recordId')
    console.log('CreateCaseAction2 - recordId - ',recordId);//This is undefined
    let urlData = component.get('v.pageReference');//parsed URL as JSON
    if(urlData.state != undefined && urlData.state.inContextOfRef != undefined){
        let inContextOfRaw = urlData.state.inContextOfRef;
        let inContextOf = inContextOfRaw.split('.')[1];//This is a base64 encoded JSON which contains the data of the main tab record
        console.log('CreateCaseAction2 - inContextOf - ',inContextOf);
        let decoded = atob(inContextOf);//Decode the base64 encoded json
        console.log('CreateCaseAction2 - decoded - ',decoded);
        let decodedJson = JSON.parse(decoded);
        console.log('CreateCaseAction2 - decodedJson - ',decodedJson);
        //Shows:
        //{
        //    "type": "standard__recordPage",
        //    "attributes": {
        //        "objectApiName": "Account",
        //        "recordId": "0011w00001lOeNpAAK",
        //        "actionName": "view"
        //    },
        //    "state": {}
        //}

        if(decodedJson.attributes != undefined && decodedJson.attributes.recordId != undefined){
            console.log('CreateCaseAction2 - decodedJson.attributes.recordId - ',decodedJson.attributes.recordId);
            component.set('v.recordId', decodedJson.attributes.recordId);//Sets the recordId 
        }
        //Sets true a flag that displays the component where the recordId is actually needed. 
        //Otherwise, that componet will be shown BEFORE this method executes and it won't have the recordId
        component.set('v.showData', true);
    }
}

Finally, your component should be like this:

<aura:component controller="Utility" implements="flexipage:availableForRecordHome,lightning:isUrlAddressable,force:hasRecordId,force:hasSObjectName,lightning:actionOverride,force:lightningQuickActionWithoutHeader"  access="global">
<aura:attribute name="recordId" type="String"/>
<aura:attribute name="showData" type="Boolean" default="false"/>
<aura:handler name="init" value="{!this}" action="{!c.initComponent}"/>
<aura:if isTrue="{!v.showData}">
    <c:CreateRecordByRT recordId="{!v.recordId}" sObjectName="Case"/>
</aura:if></aura:component>

Hope it helps, at least for us, is working perfectly

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .