2

I have created a lightning web component which is a pick-list. My intention is to pass objectApiName and fieldApiName as parameters and then render UI accordingly. So that I can reuse this component in the future.

Following is my Code.

GenericPicklist.js

import { LightningElement, api, wire } from 'lwc';

import { getPicklistValues } from 'lightning/uiObjectInfoApi';
import { getObjectInfo } from 'lightning/uiObjectInfoApi';

import CUSTOM_FIELD from '@salesforce/schema/Object__c.Field_Name__c';

export default class GenericPicklist extends LightningElement {
    @api objectApiName;
    @api fieldApiName;
    @api label;
    @api value;

    @wire(getObjectInfo, { objectApiName: '$objectApiName' })
    objectInfo

    @wire(getPicklistValues, { recordTypeId: '$objectInfo.data.defaultRecordTypeId', fieldApiName: CUSTOM_FIELD})
    CustomFieldPicklistValues;

    handleChange(event) {
        this.value = event.detail.value;
    }
}

GenericPicklist.html

<template>
    <template if:true={recordTypeId}>
            <p>New, Completed</p>
    </template>
    <template if:true={CustomFieldPicklistValues.data}>
            <lightning-combobox
                label={label}
                value={value}
                placeholder="Choose ..."
                options={CustomFieldPicklistValues.data.values}
                onchange={handleChange} >
            </lightning-combobox>
    </template>
</template>

As you can see I was able to use objectApiName variable but I was not able to use fieldApiName. When I use fieldApiName variable UI is not rendered properly.

CUSTOM_FIELD object is as follows

{
    "objectApiName" : "Object__c",
    "fieldApiName"  : "Field_Name__c"
}

I tried to pass above object to getPicklistValues using parameters. Then it did not work. But when I pass the same object with hard coded values as follows, it worked.

@wire(getPicklistValues, { recordTypeId: '$objectInfo.data.defaultRecordTypeId', fieldApiName: {"objectApiName" : "Object__c","fieldApiName"  : "Field_Name__c"}})
CustomFieldPicklistValues;

Am I doing any mistake? Why I cannot achieve this using parameters as below.

@wire(getPicklistValues, { recordTypeId: '$objectInfo.data.defaultRecordTypeId', fieldApiName: {"objectApiName" : '$objectApiName',"fieldApiName"  : '$fieldApiName'}})
CustomFieldPicklistValues;
1

The Field API structure is like

{
  "fieldApiName":"Type",
  "objectApiName":"Account"
}

I updated the code it may help you and it is working as expected to me.

HTML Code

<template>
    <div if:true={options}>
            <lightning-combobox
                label={picklistlabel}
                value={value}
                placeholder="--None--"
                options={options}
                onchange={handleChange} >
            </lightning-combobox>
    </div>
</template>

Javascript Controller

import { LightningElement, api, wire, track } from 'lwc';
import { getObjectInfo, getPicklistValues } from 'lightning/uiObjectInfoApi';

export default class GenericPicklist extends LightningElement {
    @api objectApiName;
    @api fieldApiName;

    @track value;
    @track options;
    @track picklistlabel;

    recordTypeId;
    objfiedAPIName;

    @wire(getObjectInfo, { objectApiName: '$objectApiName' })
    objectInfo(result) {
        if(result.data) {
            this.picklistlabel = result.data.fields[this.fieldApiName].label;

            this.objfiedAPIName = {};
            this.objfiedAPIName.fieldApiName = result.data.fields[this.fieldApiName].apiName;
            this.objfiedAPIName.objectApiName = result.data.apiName;

            this.recordTypeId = result.data.defaultRecordTypeId;

        }
        else if(result.error) {
            window.console.log('error ===> '+JSON.stringify(result.error));
        }
    }

  @wire(getPicklistValues, { recordTypeId: '$recordTypeId', fieldApiName: '$objfiedAPIName'})
    picklistValues({error, data}) {
        if (data) {
            window.console.log('values ===> '+JSON.stringify(data));

            let picklistOptions = [{ label: '--None--', value: '--None--'}];

            // Picklist values
            data.values.forEach(key => {
                picklistOptions.push({
                    label: key.label, 
                    value: key.value
                })
            });

            this.options = picklistOptions;

        } else if (error) {
            window.console.log('error ===> '+error);
        }
    }

    handleChange(event) {
        this.value = event.detail.value;
    }
}

Configuration File

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="reusepicklistinlwc">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>

    <targetConfigs>
        <targetConfig targets="lightning__HomePage,lightning__RecordPage">
            <property name="objectApiName" type="String" default="Account" label="Enter the Object Name"/>
            <property name="fieldApiName" type="String" default="" label="Enter Field API Name"/>
        </targetConfig>
      </targetConfigs>

</LightningComponentBundle>
0

You cannot dynamically import a field like this: import CUSTOM_FIELD from '@salesforce/schema/Object__c.Field_Name__c';

In general, I would recommend using lightning-record-form with lightning input field to achieve the requested functionality.

  • Don't think about import statement. Could you please present a reason why I cannot use parameters in second wired property. In first property I was able use objectApiName parameter. But I cannot use it in second property. – Isuru Buddhika Herath Oct 31 at 3:16

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.