[SalesForce] Error : Value provided is invalid for action parameter ‘recordId’ of type ‘Id’ in LWC imperative call to Apex

I have a simple LWC component that shows Contacts of a selected Account, i am calling the Apex method imperatively from my JS code while passing the Account recordId.

Here is the Apex method signature :

@AuraEnabled
public static List<Contact> getRelatedContacts(Id recordId)

And my JS code snippet for the imperative call :

import getRelatedContacts from '@salesforce/apex/AccountService.getRelatedContacts';
...
@api
get recordId() {
    return this._recordId;
}
set recordId(value) {
   this._recordId = value;
   this.setAttribute('recordId', value);
}
...
console.log('In getRelatedContacts : '+typeof(this._recordId)+' | '+this._recordId); => this returns string & the recordId on the client side
        getRelatedContacts({
            recordId: '$_recordId'
        })
            .then(result => {
                this.relatedContacts = result;
            })
            .catch(error => {
                this.error = error.body.message;
                console.log('Error : '+this.error);
            })
            .finally(() => {
                this.isLoading = false; 
           });;

But i am receiving this error message on the client side:

Value provided is invalid for action parameter 'recordId' of type 'Id'

I tried to change the Apex method signature to the following, and both passing '$_recordId' or '$recordId' but with no luck :

@AuraEnabled
public static List<Contact> getRelatedContacts(String recordId)

And i get the following print with a System.debug on the server side after changing the parameter type to String :

DEBUG|boatId: $_recordId or DEBUG|boatId: $recordId

Which is strange because i am using the same syntax used here

I found this document talking about the error message, but nothing about the types 'Id' and 'String'.

Please tell what i am missing and the correct way to pass a recordId to call Apex imperatively.
Thank you.

Best Answer

I have few queries on your use case.

  1. Are you using your LWC component in a record context ?

    If yes : Then the recordId is automatically set, the attribute should have @api decorator. And your implementation should work, the syntax is correct

    If No : Which means you are setting the value of the recordId, to be sent to your apex. In this case the standard attribute $recordId will not be set, since this is not a record context. Use the following syntax :

         getRelatedContacts({
         recordId: this.recordId
         })