I have a LWC that passes email and customerId (a custom field) to an Apex class that retrieves customer information from an external system. The LWC is working fine on a Lead Record Page.

We have the same customer Id field on Contact record as well. So, I would like to make this component flexible so that it can be used on Lead as well as Contact record page.

Is there a way to get this work? I would like to use the same component on Lead Record Page AND Contact Record Page.

Here is the JS code from the LWC:

import { LightningElement, wire, api } from 'lwc';
import {getRecord} from 'lightning/uiRecordApi';
import LEAD_EMAIL  from '@salesforce/schema/Lead.Email';
import LEAD_CUSTID   from '@salesforce/schema/Lead.CustId__c';
import profileInfo from '@salesforce/apex/GetProfileData.getCustInfo';

export default class ProfileData extends LightningElement {
    @api recordId;
    result = {};
    profileData = {};
    @wire(getRecord, { recordId: '$recordId', fields: [LEAD_EMAIL, LEAD_CUSTID]})

    wiredRecord({data, error}) {
        if(data) {
            const { fields } = data
            Object.keys(fields).forEach(item => {
                let value = fields[item] && fields[item].value
                this.result = { ...this.result, [item]: value}
        } else if (error) {
        if(!(this.result.CustId__c == null && this.result.Email == null))  {
            profileInfo({custId: this.result.CustId_c, email: this.result.Email})
            .then( result => {
                this.profileData = result;
            .catch (error => {
                this.error = error;

There are a couple of things you can try

  1. Using the target configs like below you can provide a configuration option for the admin to choose between lead and contact

      <targetConfig targets="lightning__AppPage, lightning__HomePage">
         <property name="sobject" datasource="Lead,Contact" type="String" />

check for the file format here

For the above, you need an @api property in your controller. For example, it will be @sobject in your js controller.

  1. Now you will have to import everything to your controller like below

    import LEAD_EMAIL from '@salesforce/schema/Lead.Email';

    import LEAD_CUSTID from '@salesforce/schema/Lead.CustId__c';

    import CONTACT_EMAIL from '@salesforce/schema/Contact.Email';

    import CONTACT_CUSTID from '@salesforce/schema/Contact.CustId__c';

Then just in the constructor() conditionally populate a variable based on sobjectproperty.


constructor() {
   if(sobject === 'Lead') {
      this.fields = [LEAD_EMAIL, LEAD_CUSTID];
   if(sobject === 'Contact') {
      this.fields = [CONTACT_EMAIL, CONTACT_CUSTID]

@wire(getRecord, { recordId: '$recordId', fields: '$fields'})

The above will only work to a certain extend. You will end up with a lot of imports if you have many such fields.

A better alternative is to use CMDT (Custom Metadata Type) for this and use apex controller.

If you need help with code, check this component from one of Sample App Gallery Apps.

  • Hi Mohith, Thank you for the suggestion. I am getting the following error message when I try this: "Cannot read property 'fields' of undefined" – Kalpesh Feb 3 at 23:58
  • Can you share which lines by sharing the code? Your variable just be undefined – Mohith Shrivastava Feb 4 at 0:11
  • I needed just one little change - like this: @wire(getRecord, { recordId: '$recordId', fields: '$fields'}) Now, I am able to use the component on both Lead and Contact. Thank you for your help Mohith. – Kalpesh Feb 4 at 0:25
  • ah yes forgot about that reactivity :) Good work!!! – Mohith Shrivastava Feb 4 at 1:22

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.