5

Hey folks so I've developed a component to pull a related opportunity Id from a case record and do some other non important things. Now the ask is to get said component to work for some other Objects related to the Opportunity. Issue is the opportunity Id API name is named different on these objects.

I've added some design attributes to pass what object the component is on. But I want to be able to adjust the fields value being fired back in the @wire

<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="TestComp">
<apiVersion>46.0</apiVersion>
<isExposed>true</isExposed>
<masterLabel>TestComp</masterLabel>
<description>TestComp</description>
<targets>
    <target>lightning__RecordPage</target>
    <target>lightning__AppPage</target>
    <target>lightning__HomePage</target>
</targets>
<targetConfigs>  
    <targetConfig targets="lightning__RecordPage">
        <property name="relatedObject" type="String" default="Case" datasource="Case,Consult,OpporunityProduct"/>
    </targetConfig>
</targetConfigs>

I want to be able to change what is passed into the below @wire as fields based on what is selected in the design attribute when the component is added to the layout. Any thoughts on how this can be done or am I missing something obvious?

import { LightningElement, api, wire, track } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';


const fields = [
    'Case.Opportunity__c'
]
//consult opportunity field would be this when on Consult-> CNSLT.OPRTY_ID__c 

export default class BoxEmbedLWC extends LightningElement {
    @api recordId;
    @api relatedObject;

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

    get returnedRecord(){
        console.log('Current Object selected is -> '+this.relatedObject)
        console.log( 'Current Record opportunity Id is ->'+this.objRec.data.fields.Opportunity__c.value)
        return this.objRec.data.fields.Opportunity__c.value;
    }
}
2
  • cna you clarify what you mean by design attribute? Are you wanting to dynamically set the fields list const fields=[...] based on the page (for example a lightning record page) this LWC is placed on? Oct 24, 2019 at 21:53
  • Hi Jordon, Yes I want to change the value being passed as fields to the @wire call based on what was selected from the metadata.xml property attribute ie datasource="Case,Consult,OpporunityProduct" so if Case was selected, fields would change to match what what the opportunity field was on case, if consult was selected the fields value would change to what the opportunity field was on consult, I hope this makes more sense. Oct 24, 2019 at 22:13

2 Answers 2

7

I eventually got this to work using a connectedCallback to set the field variable being passed into the getRecord, I also leveraged object context property. Thanks for that @jordan.baucke. Any additional improvements are welcomed, I'm new to LWC and React so learning as I go.

import { LightningElement, api, wire, track } from 'lwc';
import { getRecord  } from 'lightning/uiRecordApi';

export default class TestComponent extends LightningElement {
    @api recordId;
    @track record = '';
    @track error;
    @track currentOptyField ;
    @api objectApiName;

    connectedCallback() {
        if(this.objectApiName==='Case') {
            this.currentOptyField = 'Case.Opportunity__c';
        }
        if(this.objectApiName==='OpportunityLineItem') {
            this.currentOptyField = 'OpportunityLineItem.OpportunityId';
        }
    }
    @wire(getRecord,{recordId: '$recordId',fields: '$currentOptyField'})
    objRec({error, data}) {
        if (data) {
            this.record = data;
        } else {
            this.error = error;
        }
    }
    get optyId() {
        let theOptyId = "Opty Id not found";
        if(this.record){
            if(this.objectApiName==='Case') {
                theOptyId = this.record.fields.Opportunity__c.value;
            }
            if(this.objectApiName==='OpportunityLineItem') {
                theOptyId = this.record.fields.OpportunityId.value;
            }
        }
        return theOptyId;
    }
2

@Brendan,

Haven't tested this, but just a theory (will be heavily dependent on evaluation order in the life-cycle of the component if this will work.)

Leveraging object context property (which will populate @api objectApiName with the name of the object, create some logic in the context of the definition of the file @wire method:

import { LightningElement, api, wire, track } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';

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

    @wire(getRecord,{recordId: '$recordId', this.objectApiName === 'Case' ? ['Case.Opportunity__c'] : this.objectApiName ==='Account' ? [...] : [] })
    objRec;
}

Give it a shot ...

1
  • Looks like the @wire takes precedence over the api variable for objectApiName I'm receiving the error "Action.prototype.finishAction Error [Error in $A.getCallback() [Cannot read property 'objectApiName' of undefined] " - clever idea though Oct 25, 2019 at 0:05

You must log in to answer this question.

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