6

I have created an LWC component for quick action and also defined the @api recordId inside that. But the recordId is undefined in the component when logged. Seems like it is not being passed to the component from quick action. Why is it undefined?

3

Implement a setter for the Id and add your logic here to be executed as soon as the value is populated by SF internally.

_recordId;

@api set recordId(value) {
    this._recordId = value;

    // do your thing right here with this.recordId / value
}

get recordId() {
    return this._recordId;
}
2

For this to work, you can add {recordId} in the component html and have that in a div with style display:none and you can get the value in renderedCallback. The accepted answer above may not work for Screen type Action

Or

Create a wrapper Aura component which gets the recordId and pass in the recordId to LWC

1

Update: If you are using the Headless Action, the recordId is not available until the @api invoke() is called. You can get the recordId in invoke method.

You can get the record in the lwc quick action. Just define the recordId as a public property in your component. Please note the this is case sensitive.

To get the records fields you can use the getRecord wired method from uiRecordApi. Just pass the record Id to the getRecord method.

See the sample code below.

import { LightningElement, api } from "lwc";

export default class LwcScreenAction extends LightningElement {
    @api recordId;

    connectedCallback() {
        console.log("recordId", this.recordId);
    }
}
1
  • 4
    Thanks for responding @Rahul. I tried the below in my lightning component. ` connectedCallback(){ console.log("Inside connectedCallback() ", this.recordId); } }` It gets called, but the recordId shows undefined. recordId is declared with @api in the class. Also, the user s not directed to the lwc template, which is strange too. Any idea what could be going on here
    – Ad A
    May 25 at 17:28
1

Okay, I think I figured out what was going on. The lightning web components targeted at lightning_RecordAction are headless, so the recordId is not passed to connectedCallback(). However, it is passed to the invoke() method if the recordId has been declared appropriately.

4
  • +1 Please mark your answer as accepted so it will help others. May 26 at 7:05
  • Did you try adding it as a <target>lightning__RecordPage</target> also?
    – Adrian Larson
    Jun 1 at 17:32
  • Any chance you can give an example? I do not understand... "However, it is passed to the invoke() method if the recordId has been declared appropriately." Jun 10 at 15:45
  • @AdrianLarson No, that does not make a difference. Jul 28 at 11:09
1

EDIT: This definitely feels like a bit of a hack and a workaround, but it works until Salesforce gets us access to recordId in the connectedCallback() for Screen Action LWCs

Piggy backing off of Manikanta's answer here but this solution finally worked for me for LWC Screen Quick Actions where you need access to the record Id and it isn't available in the connectedCallback() function.

In the Javascript file we can wait until we hit rendered callback with access to the record Id by setting up that display none div with the recordId being rendered. You'll notice that the renderedCallback() function ends up getting called twice in our component. The first time on initial render, and a second time when the {recordId} variable is rendered on the page. The second render is what gives us access to the recordId.

Once we have access to the recordId we need to set retrievedRecordId to true so that we don't continuously execute some body of logic over and over.

Javascript File

import { LightningElement, api } from 'lwc';

export default class QuickActionRecordIdRetrieval extends LightningElement {

    @api recordId;
    retrievedRecordId = false;

    renderedCallback() {
        if (!this.retrievedRecordId && this.recordId) {
            
            this.retrievedRecordId = true; // Escape case from recursion
            console.log('Found recordId: ' + this.recordId);

            // Execute some function or backend controller call that needs the recordId
        }
    }
}

HTML File

<template>
    <div style="display: none;">
        {recordId}
    </div>
</template>
1

Please Try Below code you will get record id:

   @api recordId; 
   connectedCallback() {
        window.clearTimeout(this.delayTimeout);
        this.delayTimeout = setTimeout(() => {
           alert(this.recordId));
        }, 0);
    }
2
  • This works for me too.
    – Keith C
    Jul 19 at 16:51
  • But for me it doesn't. this.recordId is still undefined. Jul 28 at 11:34
1

You can check these QuickAction recipes from the lwc-recipes app of Trailhead Sample Gallery. These recipes are newly added and showcase different use-cases of Quick actions with lwc.

editRecordScreenAction - his simple recipe shows how to create a screen action with LWC. It uses recordId, retrieves the data using wire service, and updates the record using uiRecordApi.

Here is a sample usage of recordId from this recipe.

import { LightningElement, api, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';
import FIRSTNAME_FIELD from '@salesforce/schema/Contact.FirstName';
import LASTNAME_FIELD from '@salesforce/schema/Contact.LastName';

export default class EditRecordScreenAction extends LightningElement {
    @api recordId;
    @api objectApiName;

    @wire(getRecord, {
        recordId: '$recordId',
        fields: [FIRSTNAME_FIELD, LASTNAME_FIELD]
    })
    contact;

    get firstname() {
        return this.contact.data
            ? this.contact.data.fields.FirstName.value
            : null;
    }

    get lastname() {
        return this.contact.data
            ? this.contact.data.fields.LastName.value
            : null;
    }
}

You need to set this target configuration in the metafile.

 <targets>
    <target>lightning__RecordAction</target>
 </targets>
 <targetConfigs>
    <targetConfig targets="lightning__RecordAction">
        <actionType>ScreenAction</actionType>
    </targetConfig>
 </targetConfigs>

dispatchEventHeadlessAction - This recipe shows how you can create Headless Actions. It depicts how you can dispatch an event with the click of a button.

Here is the sample javascript code for the headless action from this recipe.

import { LightningElement, api } from 'lwc';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class DispatchEventHeadlessAction extends LightningElement {
    @api recordId;
    @api async invoke() {
        // Fire Toast message
        let event = new ShowToastEvent({
            title: 'I am a headless action!',
            message: 'Hi there! Starting...'
        });
        this.dispatchEvent(event);
        // Wait and fire another another Toast message
        await this.sleep(2000);
        // Fire Toast message
        event = new ShowToastEvent({
            title: 'I am a headless action on record with id ' + this.recordId,
            message: 'All done!'
        });
        this.dispatchEvent(event);
    }

    sleep(ms) {
        // eslint-disable-next-line @lwc/lwc/no-async-operation
        return new Promise((resolve) => setTimeout(resolve, ms));
    }
}

You need to set this target configuration for headless action in the metafile.

<targets>
  <target>lightning__RecordAction</target>
</targets>

<targetConfigs>
  <targetConfig targets="lightning__RecordAction">
    <actionType>Action</actionType>
  </targetConfig>
</targetConfigs>
2
  • 1
    While this may theoretically answer the question, it would be preferable to include the essential parts of the answer here, and provide the link for reference.
    – identigral
    Aug 11 at 3:17
  • 1
    Hi @identigral, Thank you. I have edited my answer accordingly. Aug 11 at 4:50
0

Yes, We also get record id from ScreenType action.

Try This: https://salesforce.stackexchange.com/a/352841/96522

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.