Insert field value and ID to dual list box from APEX controller

lightning-duallistboxlightning-web-componentswire

I am making a Lightning Web Component and for it I want to populate a dual list box with a list of records, with the value of one field being the label and the ID of the record as the value. I am using wire to pull the records via an Apex controller but really struggling to figure out how I can subsequently loop over that to push the two values into both label and value for the dual list box options.

JS

import { LightningElement, wire } from 'lwc';
import getdualRecords from '@salesforce/apex/DualListController.records';

export default class scratchtest extends LightningElement {

    _selected = [];

    options = [];
    @wire(getdualRecords , { email: '[email protected]' })
    recordresults({data,error}) {
        data && this.options = data.map(record => ({value: record.Id, label: record.Name}));
    }

    get selected() {
        return this._selected.length;
    }

    handleChange(e) {
        this._selected = e.detail.value;
    }

HTML

<template>
    <lightning-card>
        <div class="slds-p-around_small">
            <lightning-dual-listbox 
                name="testduallist"
                label="Select Records"
                source-label="Available Records"
                selected-label="Linked Records"
                field-level-help="Select records"
                options={options}
                onchange={handleChange}
                disable-reordering=true
            ></lightning-dual-listbox>
        </div>
    </lightning-card>
</template>

Apex

public class DualListController{
    @AuraEnabled(cacheable=true)
    public static List<Object__c> records(String email) {
        return  [
            SELECT Id, Name
            FROM Object__c
            WHERE Email__c = :email AND Active__c = TRUE
            WITH SECURITY_ENFORCED
        ];
    }
}

Best Answer

You can use a wire handler for this purpose:

options = [] // List of options for dual list box
@wire(getRecords, {}) getRecordsResult({data,error}) {
  data && (this.options = data.map(record => ({ value: record.Id, label: record.Name })))
}

We use Array.prototype.map to convert the incoming data from normal record format into a format suitable for the dual list box's options. Note that @track is not necessary when we use this technique, as the system detects that we have replaced the old Array object with a new Array object, and thus triggers a render cycle.

Related Topic