0

I have a picklist field which I am fetching using wire. Now the scenario is I have to fetch all the records of the selected picklist value and show the values of one of the field in records in another picklist.

Say I have Type as one Picklist then based on Type value, I need to show the Account Names in other picklist field where Type value is the selected Type.

I have written the below code till now but when I select the Type value for the 1st time it gives me "Cannot read property of length error" and when I select it for the 2nd time it doesn't give me any error but can't get Account Name values in the dependent picklist field

HTML:

<lightning-layout-item size="10" padding="horizontal-medium">
                    <lightning-combobox class="" options={typeValues} dropdown-alignment="auto" 
                       label="Type"
                        placeholder="--Select Type--" value={typeSelected} onchange= 
                              {handleTypeChange}
                        required>
                    </lightning-combobox>
</lightning-layout-item>
<lightning-layout-item size="5" padding="horizontal-medium">
                <lightning-combobox class="" options={accountNames} dropdown-alignment="auto" 
                                   label="Account"
                    placeholder="--Select Account--" value={accountSelected} onchange= 
                             {handleNameChange}
                    required disabled={isTypeSelected}>
                </lightning-combobox>
</lightning-layout-item>

JS:

import { LightningElement, wire, track } from 'lwc';
import { getPicklistValues } from 'lightning/uiObjectInfoApi';
import { getObjectInfo } from 'lightning/uiObjectInfoApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';
import TYPE_FIELD from '@salesforce/schema/Account.Type';
import getAccounts from '@salesforce/apex/MyClass.getAccounts';

export default class TestLwcPicklist extends LightningElement {
 
@track typeValues;
@track isTypeSelected = true;
@track accountNamePicklist = [];
@track typeSelected;
@wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
    objectInfo;

    @wire(getPicklistValues, { recordTypeId: '$objectInfo.data.defaultRecordTypeId', fieldApiName: TYPE_FIELD })
    typePicklistValues({ data, error }) {
        if (data) {
            this.typeValues = data.values;
            this.error = undefined;
        }
        if (error) {
            this.error = error;
            this.typeValues = undefined;
        }
    }
handleProductChange(event) {
            this.typeSelected = event.detail.value;
            this.isTypeSelected = false;
            
            this.fetchAccountNamePicklist();
        }
    
        fetchAccountNamePicklist() {
            getAccounts({ type: this.typeSelected })
                .then(result => {
                    this.account = result;
                    this.error = undefined;
                    this.account.forEach(row => {
                        let name = { label:row.Name, value:row.Name };
                        this.accountNamePicklist.push(name);
                    })
                })
                .catch(error => {
                    this.error = error;
                    this.account = undefined;
                })
                
            
    
        }
    
    get accountNames() {
            return this.accountNamePicklist;
        }
}

APEX:

@AuraEnabled
public static List<Account> getAccounts(String type){
     List<Account> lstAcc = [SELECT Id, Name, Type from Account Where Type = :type]
     return lstAcc
}
0

The property account will be undefined first time, because you have misplaced the for-loop in the below code.

fetchAccountNamePicklist() {
        getAccounts({ type: this.typeSelected })
            .then(result => {
                this.account = result;
                this.error = undefined;
            })
            .catch(error => {
                this.error = error;
                this.account = undefined;
            })

            for (var i = 0; i < this.account.length; i++) {
                this.accountNamePicklist = [...this.accountNamePicklist, { label: this.account[i].Name, value: this.account[i].Name }];
            }
    }

Which should be like this.

fetchAccountNamePicklist() {
    getAccounts({ type: this.typeSelected })
        .then(result => {
            this.account = result;
            for (let i = 0; i < this.account.length; i++) {
                this.accountNamePicklist = [...this.accountNamePicklist, { label: this.account[i].Name, value: this.account[i].Name }];
            }
            this.error = undefined;
        })
        .catch(error => {
            this.error = error;
            this.account = undefined;
        })
    }
}

Also note that as you have not used the account property anywhere else, you don't even need to store it. You can simply generate the options right there based on the result.

Also a few other improvements you can do.

  • Always use let instead of var for block-scoped variables.
  • the for-loop you have used to set accountNamePicklist is not efficient. instead of that use the array.map(). Its a bad idea to clone the array, inside the for-loop. you could have used array.push() as well.
0

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.