Este dilema se puede resolver de variadas formas, pero nosotros te dejamos la que para nosotros es la resolución más completa.
Solución:
LWC tiene un adaptador de cable que extrae los valores de la lista de selección de forma dinámica.
import LightningElement, wire, track from 'lwc';
import getPicklistValues from 'lightning/uiObjectInfoApi';
import INDUSTRY_FIELD from '@salesforce/schema/Account.Industry';
import getRecord, getFieldValue from 'lightning/uiRecordApi';
const fields = [INDUSTRY_FIELD];
export default class Example extends LightningElement
@api recordId;
@track selectedOption;
@track options;
/*
* There is no guarantee that the pick-list values will return first
* Because of this, we check to see if a selected option already exists
* If it does, we verify it is a valid value for the picklist.
* If it is not valid, we set the selected option to the default value.
* If it is valid, no changes are made
* If there is no selected option, we use the default option
*
* Note: recordTypeId is required. If your object has no record types create
* at least 1.
*/
@wire(getPicklistValues, recordTypeId: '012000000000000AAA', fieldApiName: INDUSTRY_FIELD )
setPicklistOptions(error, data)
if (data)
this.options = data.values;
if (this.selectedOption)
let optionIsValid = this.options.some(function(item)
return item.value === this.selectedOption;
, this);
if (!optionIsValid)
this.selectedOption = data.defaultValue;
else
this.selectedOption = data.defaultValue;
else if (error)
console.log(error);
/*
* As with above, there is no guarantee to which order these functions execute
* If the options list exists, we will check to see if our value is valid.
* If it is, set our value as the selected value
* If it is not, do nothing
* If the options list does not exist, we will create an options list with
* a single value using this records picklist value.
*/
@wire(getRecord, recordId:'$recordId', fields)
account(error, data)
if (data)
let industryValue = getFieldValue(data, INDUSTRY_FIELD);
if (!this.options)
this.options = [label:industryValue, value:industryValue];
let industryIsValid = options.some(function(item)
return item.value === industryValue;
, this);
if (industryIsValid)
this.selectedOption = industryValue;
else if (error)
console.log(error);
Tuve algo de tiempo libre esta mañana, y así es como puede controlar el orden de ejecución del adaptador de cable. Me equivoqué antes acerca de requerir el uso de getter/setters de uso, lo importante es en realidad cómo (re) invocas con fuerza el cable.
Los cables se invocan en función de algún tipo de cambio (la parte reactiva) y un null
para truthy
change es una forma perfectamente válida de (re) invocarlo.
Si revisas los dos error
y data
cuando se suministra con un var reactivo falso/indefinido cuando se construye el componente, ambos vuelven indefinidos y fallan en silencio (esto es bueno).
Sin embargo, algo como esto (re) invocará un adaptador de cable:
import LightningElement, api, wire, track from 'lwc';
import getPicklistValues from 'lightning/uiObjectInfoApi';
import TYPE_FIELD from '@salesforce/schema/Account.Type';
import getRecord, getFieldValue from 'lightning/uiRecordApi';
const fields = [TYPE_FIELD];
export default class Example extends LightningElement
@api recordId;
@track selectedOption;
@track options;
// private
_recordTypeId;
// Step 1
@wire(getRecord, recordId:'$recordId', fields)
account(error, data)
if (data)
let typeValue = getFieldValue(data, TYPE_FIELD);
this.selectedOption = typeValue;
this._recordTypeId = '012000000000000AAA'; // setting this value will re-invoke the wire
else if (error)
console.log(error);
// Step 2, determined by when the reactive bind is changed
@wire(getPicklistValues, recordTypeId: '$_recordTypeId', fieldApiName: TYPE_FIELD )
setPicklistOptions(error, data)
if (data)
// Apparently combobox doesn't like it if you dont supply any options at all.
// Even though selectedOption was assigned in step 1, it wont "select" it unless it also has options
this.options = data.values;
else if (error)
console.log(error);