function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
fiona gentryfiona gentry 

I see Blank values in dependent picklist using SFDCMonkey Blog

Hi Gurus,

I am trying to fetch dependent picklist values by referring 
https://sfdcmonkey.com/2018/08/31/dependent-picklist-lightningselect-lightning-salesforce/
 and 
https://developer.salesforce.com/forums/?id=9060G0000005pt3QAA

Here is problem as you see I see no drop down value in "Country" controlling field 

can some one please help ,in the blog they used contact standard object and here I have used custom object and its API name
which is ERT_Case_Type__c

here is my cmp file
 
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction"
                access="global"
                controller="dependentPicklist_UpdateCtrl">
    <!-- call doInit function on component load -->  
    <aura:handler name="init" value="this" action="{!c.doInit}"/>
    
    <!-- aura attributes-->  
    <aura:attribute name="listControllingValues" type="list" default="[]" description="to store controller field values"/>
    <aura:attribute name="listDependingValues" type="list" default="['--- None ---']" description="to store dependent field values"/>
    <aura:attribute name="listSubDependingValues" type="list" default="['--- None ---']" description="to store dependent field values"/>
    
    <aura:attribute name="depnedentFieldMap" type="map" description="map to store dependent values with controlling value"/>
    <aura:attribute name="subDepnedentFieldMap" type="map" description="map to store sub dependent values with controlling value"/>
    <aura:attribute name="bDisabledDependentFld" type="boolean" default="true"/> 
    <aura:attribute name="bDisabledSubDependentFld" type="boolean" default="true"/> 
    
    
    <aura:attribute name="objDetail" type="ERT_Case_Type__c" default="{'sobjectType' : 'ERT_Case_Type__c'}"/>
    <aura:attribute name="controllingFieldAPI" type="string" default="Level_1__c" description="store field API name of Controller field"/>
    <aura:attribute name="dependingFieldAPI" type="string" default="Level_2__c" description="store field API name of dependent field"/>
    <aura:attribute name="subDependingFieldAPI" type="string" default="Level_3__c" description="store field API name of sub dependent field"/>
    
    <!--Controller Field-->
    <lightning:layoutItem size="12" padding="around-small">    
        <lightning:select name="controllerFld"
                          value="{!v.objDetail.Level_1__c}"
                          label="Country"
                          onchange="{!c.onControllerFieldChange}">
            <aura:iteration items="{!v.listControllingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
    </lightning:layoutItem>
    
    <!--Dependent Field-->
    <lightning:layoutItem size="12" padding="around-small">
        <lightning:select name="dependentFld"
                          value="{!v.objDetail.Level_2__c}"
                          label="City"
                          disabled="{!v.bDisabledDependentFld}"
                          onchange="{!c.onSubControllerFieldChange}">
            <aura:iteration items="{!v.listDependingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
    </lightning:layoutItem>
    
    <!--sub Dependent Field-->
    <lightning:layoutItem size="12" padding="around-small">
        <lightning:select name="subDependentFld"
                          value="{!v.objDetail.Level_3__c}"
                          label="language"
                          disabled="{!v.bDisabledSubDependentFld}">
            <aura:iteration items="{!v.listSubDependingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
    </lightning:layoutItem>
    
</aura:component>
Your help is highly appreciated

Regards,
Fiona

 
Best Answer chosen by fiona gentry
ravi soniravi soni
hi fiona,
your Depandencies are right. I have checked following  code many time on different  objects. I am sure this time it's working properly.
I did change object and fields name with your object and fields name. but even then you have to check once api Name.
and this  time first of all you should create apex class and then aura Component.
public class dependentPicklist_UpdateCtrl {
    @AuraEnabled 
    public static  Map<String,Map<string,list<string>>> getDependentMap(sObject objDetail, string contrfieldApiName,string depfieldApiName, string subDepFieldAPI) {
        String controllingField = contrfieldApiName.toLowerCase();
        String dependentField = depfieldApiName.toLowerCase();
        String subdependingFieldAPI = subDepFieldAPI.toLowerCase();
        
        Map<String,List<String>> objResults = new Map<String,List<String>>();
        Map<string,list<string>> lstDepandingMap = new Map<string,list<string>>();
        Map<String,Map<string,list<string>>> lstObjResults = new Map<String,Map<string,list<string>>>();
        
        Schema.sObjectType objType = objDetail.getSObjectType();
        if (objType==null){
            //return objResults;
            return lstObjResults;
        }
        
        Map<String, Schema.SObjectField> objFieldMap = objType.getDescribe().fields.getMap();
        
        if (!objFieldMap.containsKey(controllingField) || !objFieldMap.containsKey(dependentField) ||  !objFieldMap.containsKey(subdependingFieldAPI)){
            //return objResults;
            return lstObjResults;
        }
        
        Schema.SObjectField theField = objFieldMap.get(dependentField);
        Schema.SObjectField ctrlField = objFieldMap.get(controllingField);
        Schema.SObjectField subctrlField = objFieldMap.get(subdependingFieldAPI);
        
        List<Schema.PicklistEntry> contrEntries = ctrlField.getDescribe().getPicklistValues();
        List<PicklistEntryWrapper> depEntries = wrapPicklistEntries(theField.getDescribe().getPicklistValues());
        List<PicklistEntryWrapper> subDepEntries = wrapPicklistEntries(subctrlField.getDescribe().getPicklistValues());
        List<String> controllingValues = new List<String>();
        List<String> dependingValues = new List<String>();
        
        for (Schema.PicklistEntry ple : contrEntries) {
            String label = ple.getLabel();
            objResults.put(label, new List<String>());
            controllingValues.add(label);
        }
         
        for (PicklistEntryWrapper plew : depEntries) {
            
            String label = plew.label;
            String validForBits = base64ToBits(plew.validFor);
            for (Integer i = 0; i < validForBits.length(); i++) {
                String bit = validForBits.mid(i, 1); 
             
                if (bit == '1') {
                     objResults.get(controllingValues.get(i)).add(label);
                     dependingValues.add(label);
                     lstDepandingMap.put(label, new List<String>());
                      }
            } 
        }
          for (PicklistEntryWrapper plew : subDepEntries) {
            String label = plew.label;
             String validForBits = base64ToBits(plew.validFor);
              for (Integer i = 0; i < validForBits.length(); i++) {
                String bit = validForBits.mid(i, 1);
                
                 if (bit == '1') {
                       lstDepandingMap.get(dependingValues.get(i)).add(label);
                   
                }
            }
        }
        
          Map<string,list<string>> lstDepMap = new Map<string,list<string>>();
        
        
        for(string key : objResults.keySet()){
            
              lstObjResults.put(key,new Map<string,list<string>>());
            
            for( string depindingKey : objResults.get(key)){
                     lstDepMap.put(depindingKey,lstDepandingMap.get(depindingKey));
            }
                   lstObjResults.put(key,lstDepMap);
            lstDepMap = new Map<string,list<string>>();
        }
         
         
         system.debug('lstObjResults===> ' + lstObjResults);
        //return objResults;
    return lstObjResults;
    }
     
    public static String decimalToBinary(Integer val) {
        String bits = '';
        while (val > 0) {
            Integer remainder = Math.mod(val, 2);
            val = Integer.valueOf(Math.floor(val / 2));
            bits = String.valueOf(remainder) + bits;
        }
        return bits;
    }
    
    public static String base64ToBits(String validFor) {
        if (String.isEmpty(validFor)) return '';
        
        String validForBits = '';
        
        for (Integer i = 0; i < validFor.length(); i++) {
            String thisChar = validFor.mid(i, 1);
            Integer val = base64Chars.indexOf(thisChar);
            String bits = decimalToBinary(val).leftPad(6, '0');
            validForBits += bits;
        }
        
        return validForBits;
    }
    
    private static final String base64Chars = '' +
        'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
        'abcdefghijklmnopqrstuvwxyz' +
        '0123456789+/';
    
    
    private static List<PicklistEntryWrapper> wrapPicklistEntries(List<Schema.PicklistEntry> PLEs) {
        return (List<PicklistEntryWrapper>)
            JSON.deserialize(JSON.serialize(PLEs), List<PicklistEntryWrapper>.class);
    }
    
    public class PicklistEntryWrapper{
        public String active {get;set;}
        public String defaultValue {get;set;}
        public String label {get;set;}
        public String value {get;set;}
        public String validFor {get;set;}
        public PicklistEntryWrapper(){            
        }
        
    }
    public class wrapperOfMap{
        
    }
    
  
}
 
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction"
                access="global"
                controller="dependentPicklist_UpdateCtrl">
    <!-- call doInit function on component load -->  
    <aura:handler name="init" value="this" action="{!c.doInit}"/>
    


    <!-- aura attributes-->  <!---->
    <aura:attribute name="listControllingValues" type="list" default="[]" description="to store controller field values"/>
    <aura:attribute name="listDependingValues" type="list" default="['--- None ---']" description="to store dependent field values"/>
    <aura:attribute name="listSubDependingValues" type="list" default="['--- None ---']" description="to store dependent field values"/>
    <aura:attribute name="depnedentFieldMap" type="map" description="map to store dependent values with controlling value"/>
    <aura:attribute name="SubdepnedentFieldMap" type="map" description="map to store dependent values with controlling value"/>
    <aura:attribute name="bDisabledDependentFld" type="boolean" default="true"/> 
    <aura:attribute name="bDisabledSubDependentFld" type="boolean" default="true"/> 
    
    <!--<aura:attribute name="objDetail" type="contact" default="{'sobjectType' : 'contact'}"/>-->
    <aura:attribute name="objDetail" type="ERT_Case_Type__c" default="{'sobjectType' : 'ERT_Case_Type__c'}"/>
    <aura:attribute name="controllingFieldAPI" type="string" default="Level_1__c" description="store field API name of Controller field"/>
    <aura:attribute name="dependingFieldAPI" type="string" default="Level_2__c" description="store field API name of dependent field"/>
    <aura:attribute name="subDependingFieldAPI" type="string" default="Level_3__c" description="store field API name of dependent field"/>
    
    <!--Controller Field-->
    <lightning:layoutItem size="12" padding="around-small">    
        <lightning:select name="controllerFld"
                          value="{!v.objDetail.Level_1__c}"
                           label="Country"
                          onchange="{!c.onControllerFieldChange}">
            <aura:iteration items="{!v.listControllingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
    </lightning:layoutItem>
    
    <!--Dependent Field-->
    <lightning:layoutItem size="12" padding="around-small">
        <lightning:select name="dependentFld"
                          value="{!v.objDetail.Level_2__c}"
                          label="State"
                          disabled="{!v.bDisabledDependentFld}"
                            onchange="{!c.onDepandingFieldChange}">
            <aura:iteration items="{!v.listDependingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
    </lightning:layoutItem>
        <!--SubDependent Field-->
    <lightning:layoutItem size="12" padding="around-small">
        <lightning:select name="dependentFld"
                          value="{!v.objDetail.Level_3__c}"
                          label="City"
                          disabled="{!v.bDisabledSubDependentFld}">
            <aura:iteration items="{!v.listSubDependingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
    </lightning:layoutItem>
    
</aura:component>
 
({
    doInit : function(component, event, helper) { 
        // get the fields API name and pass it to helper function  
        var controllingFieldAPI = component.get("v.controllingFieldAPI");
        var dependingFieldAPI = component.get("v.dependingFieldAPI");
        var subDepFieldAPI = component.get("v.subDependingFieldAPI"); 
        var objDetails = component.get("v.objDetail");
        // call the helper function
        helper.fetchPicklistValues(component,objDetails,controllingFieldAPI, dependingFieldAPI,subDepFieldAPI);
    },
    
    onControllerFieldChange : function(component, event, helper) {     
        var controllerValueKey = event.getSource().get("v.value"); // get selected controller field value
        var depnedentFieldMap = component.get("v.depnedentFieldMap");
         component.set("v.listSubDependingValues", ['--- None ---']);
         component.set("v.bDisabledSubDependentFld" , true);
        if (controllerValueKey != '--- None ---') {
            var ListOfDependentFields = depnedentFieldMap[controllerValueKey];
            component.set('v.SubdepnedentFieldMap',ListOfDependentFields);
             var listDepVal = []; 
            for(let depVal in ListOfDependentFields){
                  listDepVal.push(depVal);
            }
          
            if(listDepVal.length > 0){
                component.set("v.bDisabledDependentFld" , false);  
                helper.fetchDepValues(component, listDepVal,true);    
            }else{
                component.set("v.bDisabledDependentFld" , true); 
                component.set("v.listDependingValues", ['--- None ---']);
            }  
            
        } else {
            component.set("v.listDependingValues", ['--- None ---']);
            component.set("v.bDisabledDependentFld" , true);
            component.set("v.bDisabledSubDependentFld" , true);
        }
    },
    
    onDepandingFieldChange: function(component, event, helper) {   
     var depandingValueKey = event.getSource().get("v.value"); // get selected controller field value
        var depnedentFieldMap = component.get("v.SubdepnedentFieldMap");
        
        if (depandingValueKey != '--- None ---') {
            var ListOfDependentFields = depnedentFieldMap[depandingValueKey];
            console.log('ListOfDependentFields===> ' + ListOfDependentFields);
            
            var listDepVal = []; 
            for(let depVal in ListOfDependentFields){
                  listDepVal.push(ListOfDependentFields[depVal]	);
            }
          console.log('listDepVal========> ' + listDepVal);
            if(listDepVal.length > 0){
                component.set("v.bDisabledSubDependentFld" , false);  
                helper.fetchDepValues(component, listDepVal,false);    
            }else{
                component.set("v.bDisabledSubDependentFld" , true); 
                component.set("v.listSubDependingValues", ['--- None ---']);
            }  
            
        } else {
            component.set("v.listSubDependingValues", ['--- None ---']);
            component.set("v.bDisabledSubDependentFld" , true);
        }
    },
    
})
 
({
    fetchPicklistValues: function(component,objDetails,controllerField, dependentField,subDepFieldAPI) {
        // call the server side function  
        var action = component.get("c.getDependentMap");
        // pass paramerters [object definition , contrller field name ,dependent field name] -
        // to server side function 
        action.setParams({
            'objDetail' : objDetails,
            'contrfieldApiName': controllerField,
            'depfieldApiName': dependentField,
            'subDepFieldAPI' : subDepFieldAPI 
        });
        //set callback   
        action.setCallback(this, function(response) {
            alert(response.getState() == "SUCCESS");
            if (response.getState() == "SUCCESS") {
                //store the return response from server (map<string,List<string>>)  
                var StoreResponse = response.getReturnValue();
                console.log('StoreResponse===> ' + JSON.stringify(StoreResponse));
                // once set #StoreResponse to depnedentFieldMap attribute 
                component.set("v.depnedentFieldMap",StoreResponse);
                
                // create a empty array for store map keys(@@--->which is controller picklist values) 
                var listOfkeys = []; // for store all map keys (controller picklist values)
                var ControllerField = []; // for store controller picklist value to set on lightning:select. 
                
                // play a for loop on Return map 
                // and fill the all map key on listOfkeys variable.
                for (var singlekey in StoreResponse) {
                    listOfkeys.push(singlekey);
                }
                
                //set the controller field value for lightning:select
                if (listOfkeys != undefined && listOfkeys.length > 0) {
                    ControllerField.push('--- None ---');
                }
                
                for (var i = 0; i < listOfkeys.length; i++) {
                    ControllerField.push(listOfkeys[i]);
                }  
                // set the ControllerField variable values to country(controller picklist field)
                component.set("v.listControllingValues", ControllerField);
            }else{
                alert('Something went wrong..');
            }
        });
        $A.enqueueAction(action);
    },
    
    fetchDepValues: function(component, ListOfDependentFields,hasDepandingList) {
        // create a empty array var for store dependent picklist values for controller field  
        var dependentFields = [];
        dependentFields.push('--- None ---');
        for (var i = 0; i < ListOfDependentFields.length; i++) {
            dependentFields.push(ListOfDependentFields[i]);
        }
        // set the dependentFields variable values to store(dependent picklist field) on lightning:select
        if(hasDepandingList){
             component.set("v.listDependingValues", dependentFields);
        }
        else {
             component.set("v.listSubDependingValues", dependentFields);
        }
       
        
    },
    
})

let me  know it's  working or not. and try this code on another object.
wating of your  response
Thank you

All Answers

ravi soniravi soni
hi fiona,
try this following code.
 Please let me know if it's helps you, do mark this answer as best so that others facing the same issue will find this information useful.
 
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction"
                access="global"
                controller="dependentPicklist_UpdateCtrl">
    <!-- call doInit function on component load -->  
    <aura:handler name="init" value="this" action="{!c.doInit}"/>
    
    <!-- aura attributes-->  
    <aura:attribute name="listControllingValues" type="list" default="[]" description="to store controller field values"/>
    <aura:attribute name="listDependingValues" type="list" default="['--- None ---']" description="to store dependent field values"/>
    <aura:attribute name="listSubDependingValues" type="list" default="['--- None ---']" description="to store dependent field values"/>
    <aura:attribute name="depnedentFieldMap" type="map" description="map to store dependent values with controlling value"/>
    <aura:attribute name="SubdepnedentFieldMap" type="map" description="map to store dependent values with controlling value"/>
    <aura:attribute name="bDisabledDependentFld" type="boolean" default="true"/> 
    <aura:attribute name="bDisabledSubDependentFld" type="boolean" default="true"/> 
    
    <aura:attribute name="objDetail" type="contact" default="{'sobjectType' : 'contact'}"/>
    <aura:attribute name="controllingFieldAPI" type="string" default="Country__c" description="store field API name of Controller field"/>
    <aura:attribute name="dependingFieldAPI" type="string" default="State__c" description="store field API name of dependent field"/>
    <aura:attribute name="subDependingFieldAPI" type="string" default="City__c" description="store field API name of dependent field"/>
    
    <!--Controller Field-->
    <lightning:layoutItem size="12" padding="around-small">    
        <lightning:select name="controllerFld"
                          value="{!v.objDetail.Country__c}"
                           label="Country"
                          onchange="{!c.onControllerFieldChange}">
            <aura:iteration items="{!v.listControllingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
    </lightning:layoutItem>
    
    <!--Dependent Field-->
    <lightning:layoutItem size="12" padding="around-small">
        <lightning:select name="dependentFld"
                          value="{!v.objDetail.State__C}"
                          label="State"
                          disabled="{!v.bDisabledDependentFld}"
                            onchange="{!c.onDepandingFieldChange}">
            <aura:iteration items="{!v.listDependingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
    </lightning:layoutItem>
        <!--SubDependent Field-->
    <lightning:layoutItem size="12" padding="around-small">
        <lightning:select name="dependentFld"
                          value="{!v.objDetail.City__c}"
                          label="City"
                          disabled="{!v.bDisabledSubDependentFld}">
            <aura:iteration items="{!v.listSubDependingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
    </lightning:layoutItem>
    
</aura:component>

JS File
({
    doInit : function(component, event, helper) { 
        // get the fields API name and pass it to helper function  
        var controllingFieldAPI = component.get("v.controllingFieldAPI");
        var dependingFieldAPI = component.get("v.dependingFieldAPI");
        var subDepFieldAPI = component.get("v.subDependingFieldAPI"); 
        var objDetails = component.get("v.objDetail");
        // call the helper function
        helper.fetchPicklistValues(component,objDetails,controllingFieldAPI, dependingFieldAPI,subDepFieldAPI);
    },
    
    onControllerFieldChange : function(component, event, helper) {     
        var controllerValueKey = event.getSource().get("v.value"); // get selected controller field value
        var depnedentFieldMap = component.get("v.depnedentFieldMap");
         component.set("v.listSubDependingValues", ['--- None ---']);
         component.set("v.bDisabledSubDependentFld" , true);
        if (controllerValueKey != '--- None ---') {
            var ListOfDependentFields = depnedentFieldMap[controllerValueKey];
            component.set('v.SubdepnedentFieldMap',ListOfDependentFields);
             var listDepVal = []; 
            for(let depVal in ListOfDependentFields){
                  listDepVal.push(depVal);
            }
          
            if(listDepVal.length > 0){
                component.set("v.bDisabledDependentFld" , false);  
                helper.fetchDepValues(component, listDepVal,true);    
            }else{
                component.set("v.bDisabledDependentFld" , true); 
                component.set("v.listDependingValues", ['--- None ---']);
            }  
            
        } else {
            component.set("v.listDependingValues", ['--- None ---']);
            component.set("v.bDisabledDependentFld" , true);
            component.set("v.bDisabledSubDependentFld" , true);
        }
    },
    
    onDepandingFieldChange: function(component, event, helper) {   
     var depandingValueKey = event.getSource().get("v.value"); // get selected controller field value
        var depnedentFieldMap = component.get("v.SubdepnedentFieldMap");
        
        if (depandingValueKey != '--- None ---') {
            var ListOfDependentFields = depnedentFieldMap[depandingValueKey];
            console.log('ListOfDependentFields===> ' + ListOfDependentFields);
            
            var listDepVal = []; 
            for(let depVal in ListOfDependentFields){
                  listDepVal.push(ListOfDependentFields[depVal]	);
            }
          console.log('listDepVal========> ' + listDepVal);
            if(listDepVal.length > 0){
                component.set("v.bDisabledSubDependentFld" , false);  
                helper.fetchDepValues(component, listDepVal,false);    
            }else{
                component.set("v.bDisabledSubDependentFld" , true); 
                component.set("v.listSubDependingValues", ['--- None ---']);
            }  
            
        } else {
            component.set("v.listSubDependingValues", ['--- None ---']);
            component.set("v.bDisabledSubDependentFld" , true);
        }
    },
    
})

Helper File
({
    fetchPicklistValues: function(component,objDetails,controllerField, dependentField,subDepFieldAPI) {
        // call the server side function  
        var action = component.get("c.getDependentMap");
        // pass paramerters [object definition , contrller field name ,dependent field name] -
        // to server side function 
        action.setParams({
            'objDetail' : objDetails,
            'contrfieldApiName': controllerField,
            'depfieldApiName': dependentField,
            'subDepFieldAPI' : subDepFieldAPI 
        });
        //set callback   
        action.setCallback(this, function(response) {
            alert(response.getState() == "SUCCESS");
            if (response.getState() == "SUCCESS") {
                //store the return response from server (map<string,List<string>>)  
                var StoreResponse = response.getReturnValue();
                console.log('StoreResponse===> ' + JSON.stringify(StoreResponse));
                // once set #StoreResponse to depnedentFieldMap attribute 
                component.set("v.depnedentFieldMap",StoreResponse);
                
                // create a empty array for store map keys(@@--->which is controller picklist values) 
                var listOfkeys = []; // for store all map keys (controller picklist values)
                var ControllerField = []; // for store controller picklist value to set on lightning:select. 
                
                // play a for loop on Return map 
                // and fill the all map key on listOfkeys variable.
                for (var singlekey in StoreResponse) {
                    listOfkeys.push(singlekey);
                }
                
                //set the controller field value for lightning:select
                if (listOfkeys != undefined && listOfkeys.length > 0) {
                    ControllerField.push('--- None ---');
                }
                
                for (var i = 0; i < listOfkeys.length; i++) {
                    ControllerField.push(listOfkeys[i]);
                }  
                // set the ControllerField variable values to country(controller picklist field)
                component.set("v.listControllingValues", ControllerField);
            }else{
                alert('Something went wrong..');
            }
        });
        $A.enqueueAction(action);
    },
    
    fetchDepValues: function(component, ListOfDependentFields,hasDepandingList) {
        // create a empty array var for store dependent picklist values for controller field  
        var dependentFields = [];
        dependentFields.push('--- None ---');
        for (var i = 0; i < ListOfDependentFields.length; i++) {
            dependentFields.push(ListOfDependentFields[i]);
        }
        // set the dependentFields variable values to store(dependent picklist field) on lightning:select
        if(hasDepandingList){
             component.set("v.listDependingValues", dependentFields);
        }
        else {
             component.set("v.listSubDependingValues", dependentFields);
        }
       
        
    },
    
})

​​​​​​​​​​​​​​Apex
public class dependentPicklist_UpdateCtrl {
    @AuraEnabled 
    public static  Map<String,Map<string,list<string>>> getDependentMap(sObject objDetail, string contrfieldApiName,string depfieldApiName, string subDepFieldAPI) {
        String controllingField = contrfieldApiName.toLowerCase();
        String dependentField = depfieldApiName.toLowerCase();
        String subdependingFieldAPI = subDepFieldAPI.toLowerCase();
        
        Map<String,List<String>> objResults = new Map<String,List<String>>();
        Map<string,list<string>> lstDepandingMap = new Map<string,list<string>>();
        Map<String,Map<string,list<string>>> lstObjResults = new Map<String,Map<string,list<string>>>();
        
        Schema.sObjectType objType = objDetail.getSObjectType();
        if (objType==null){
            //return objResults;
            return lstObjResults;
        }
        
        Map<String, Schema.SObjectField> objFieldMap = objType.getDescribe().fields.getMap();
        
        if (!objFieldMap.containsKey(controllingField) || !objFieldMap.containsKey(dependentField) ||  !objFieldMap.containsKey(subdependingFieldAPI)){
            //return objResults;
            return lstObjResults;
        }
        
        Schema.SObjectField theField = objFieldMap.get(dependentField);
        Schema.SObjectField ctrlField = objFieldMap.get(controllingField);
        Schema.SObjectField subctrlField = objFieldMap.get(subdependingFieldAPI);
        
        List<Schema.PicklistEntry> contrEntries = ctrlField.getDescribe().getPicklistValues();
        List<PicklistEntryWrapper> depEntries = wrapPicklistEntries(theField.getDescribe().getPicklistValues());
        List<PicklistEntryWrapper> subDepEntries = wrapPicklistEntries(subctrlField.getDescribe().getPicklistValues());
        List<String> controllingValues = new List<String>();
        List<String> dependingValues = new List<String>();
        
        for (Schema.PicklistEntry ple : contrEntries) {
            String label = ple.getLabel();
            objResults.put(label, new List<String>());
            controllingValues.add(label);
        }
         
        for (PicklistEntryWrapper plew : depEntries) {
            
            String label = plew.label;
            String validForBits = base64ToBits(plew.validFor);
            for (Integer i = 0; i < validForBits.length(); i++) {
                String bit = validForBits.mid(i, 1); 
             
                if (bit == '1') {
                     objResults.get(controllingValues.get(i)).add(label);
                     dependingValues.add(label);
                     lstDepandingMap.put(label, new List<String>());
                      }
            } 
        }
          for (PicklistEntryWrapper plew : subDepEntries) {
            String label = plew.label;
             String validForBits = base64ToBits(plew.validFor);
              for (Integer i = 0; i < validForBits.length(); i++) {
                String bit = validForBits.mid(i, 1);
                
                 if (bit == '1') {
                       lstDepandingMap.get(dependingValues.get(i)).add(label);
                   
                }
            }
        }
        
          Map<string,list<string>> lstDepMap = new Map<string,list<string>>();
        
        
        for(string key : objResults.keySet()){
            
              lstObjResults.put(key,new Map<string,list<string>>());
            
            for( string depindingKey : objResults.get(key)){
                     lstDepMap.put(depindingKey,lstDepandingMap.get(depindingKey));
            }
                   lstObjResults.put(key,lstDepMap);
            lstDepMap = new Map<string,list<string>>();
        }
         
         
         system.debug('lstObjResults===> ' + lstObjResults);
        //return objResults;
    return lstObjResults;
    }
     
    public static String decimalToBinary(Integer val) {
        String bits = '';
        while (val > 0) {
            Integer remainder = Math.mod(val, 2);
            val = Integer.valueOf(Math.floor(val / 2));
            bits = String.valueOf(remainder) + bits;
        }
        return bits;
    }
    
    public static String base64ToBits(String validFor) {
        if (String.isEmpty(validFor)) return '';
        
        String validForBits = '';
        
        for (Integer i = 0; i < validFor.length(); i++) {
            String thisChar = validFor.mid(i, 1);
            Integer val = base64Chars.indexOf(thisChar);
            String bits = decimalToBinary(val).leftPad(6, '0');
            validForBits += bits;
        }
        
        return validForBits;
    }
    
    private static final String base64Chars = '' +
        'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
        'abcdefghijklmnopqrstuvwxyz' +
        '0123456789+/';
    
    
    private static List<PicklistEntryWrapper> wrapPicklistEntries(List<Schema.PicklistEntry> PLEs) {
        return (List<PicklistEntryWrapper>)
            JSON.deserialize(JSON.serialize(PLEs), List<PicklistEntryWrapper>.class);
    }
    
    public class PicklistEntryWrapper{
        public String active {get;set;}
        public String defaultValue {get;set;}
        public String label {get;set;}
        public String value {get;set;}
        public String validFor {get;set;}
        public PicklistEntryWrapper(){            
        }
        
    }
    public class wrapperOfMap{
        
    }
    
  
}

Thank you
fiona gentryfiona gentry
hey veer,that didnt worked again :( can you suggest what might be the problem does it mean this code doesn't works for custom object and dependent fields?User-added image
ravi soniravi soni
hi fiona, 
Please show me your Dependeinces fields And Object
Thank you
fiona gentryfiona gentry
User-added image
ravi soniravi soni
hi fiona,
your Depandencies are right. I have checked following  code many time on different  objects. I am sure this time it's working properly.
I did change object and fields name with your object and fields name. but even then you have to check once api Name.
and this  time first of all you should create apex class and then aura Component.
public class dependentPicklist_UpdateCtrl {
    @AuraEnabled 
    public static  Map<String,Map<string,list<string>>> getDependentMap(sObject objDetail, string contrfieldApiName,string depfieldApiName, string subDepFieldAPI) {
        String controllingField = contrfieldApiName.toLowerCase();
        String dependentField = depfieldApiName.toLowerCase();
        String subdependingFieldAPI = subDepFieldAPI.toLowerCase();
        
        Map<String,List<String>> objResults = new Map<String,List<String>>();
        Map<string,list<string>> lstDepandingMap = new Map<string,list<string>>();
        Map<String,Map<string,list<string>>> lstObjResults = new Map<String,Map<string,list<string>>>();
        
        Schema.sObjectType objType = objDetail.getSObjectType();
        if (objType==null){
            //return objResults;
            return lstObjResults;
        }
        
        Map<String, Schema.SObjectField> objFieldMap = objType.getDescribe().fields.getMap();
        
        if (!objFieldMap.containsKey(controllingField) || !objFieldMap.containsKey(dependentField) ||  !objFieldMap.containsKey(subdependingFieldAPI)){
            //return objResults;
            return lstObjResults;
        }
        
        Schema.SObjectField theField = objFieldMap.get(dependentField);
        Schema.SObjectField ctrlField = objFieldMap.get(controllingField);
        Schema.SObjectField subctrlField = objFieldMap.get(subdependingFieldAPI);
        
        List<Schema.PicklistEntry> contrEntries = ctrlField.getDescribe().getPicklistValues();
        List<PicklistEntryWrapper> depEntries = wrapPicklistEntries(theField.getDescribe().getPicklistValues());
        List<PicklistEntryWrapper> subDepEntries = wrapPicklistEntries(subctrlField.getDescribe().getPicklistValues());
        List<String> controllingValues = new List<String>();
        List<String> dependingValues = new List<String>();
        
        for (Schema.PicklistEntry ple : contrEntries) {
            String label = ple.getLabel();
            objResults.put(label, new List<String>());
            controllingValues.add(label);
        }
         
        for (PicklistEntryWrapper plew : depEntries) {
            
            String label = plew.label;
            String validForBits = base64ToBits(plew.validFor);
            for (Integer i = 0; i < validForBits.length(); i++) {
                String bit = validForBits.mid(i, 1); 
             
                if (bit == '1') {
                     objResults.get(controllingValues.get(i)).add(label);
                     dependingValues.add(label);
                     lstDepandingMap.put(label, new List<String>());
                      }
            } 
        }
          for (PicklistEntryWrapper plew : subDepEntries) {
            String label = plew.label;
             String validForBits = base64ToBits(plew.validFor);
              for (Integer i = 0; i < validForBits.length(); i++) {
                String bit = validForBits.mid(i, 1);
                
                 if (bit == '1') {
                       lstDepandingMap.get(dependingValues.get(i)).add(label);
                   
                }
            }
        }
        
          Map<string,list<string>> lstDepMap = new Map<string,list<string>>();
        
        
        for(string key : objResults.keySet()){
            
              lstObjResults.put(key,new Map<string,list<string>>());
            
            for( string depindingKey : objResults.get(key)){
                     lstDepMap.put(depindingKey,lstDepandingMap.get(depindingKey));
            }
                   lstObjResults.put(key,lstDepMap);
            lstDepMap = new Map<string,list<string>>();
        }
         
         
         system.debug('lstObjResults===> ' + lstObjResults);
        //return objResults;
    return lstObjResults;
    }
     
    public static String decimalToBinary(Integer val) {
        String bits = '';
        while (val > 0) {
            Integer remainder = Math.mod(val, 2);
            val = Integer.valueOf(Math.floor(val / 2));
            bits = String.valueOf(remainder) + bits;
        }
        return bits;
    }
    
    public static String base64ToBits(String validFor) {
        if (String.isEmpty(validFor)) return '';
        
        String validForBits = '';
        
        for (Integer i = 0; i < validFor.length(); i++) {
            String thisChar = validFor.mid(i, 1);
            Integer val = base64Chars.indexOf(thisChar);
            String bits = decimalToBinary(val).leftPad(6, '0');
            validForBits += bits;
        }
        
        return validForBits;
    }
    
    private static final String base64Chars = '' +
        'ABCDEFGHIJKLMNOPQRSTUVWXYZ' +
        'abcdefghijklmnopqrstuvwxyz' +
        '0123456789+/';
    
    
    private static List<PicklistEntryWrapper> wrapPicklistEntries(List<Schema.PicklistEntry> PLEs) {
        return (List<PicklistEntryWrapper>)
            JSON.deserialize(JSON.serialize(PLEs), List<PicklistEntryWrapper>.class);
    }
    
    public class PicklistEntryWrapper{
        public String active {get;set;}
        public String defaultValue {get;set;}
        public String label {get;set;}
        public String value {get;set;}
        public String validFor {get;set;}
        public PicklistEntryWrapper(){            
        }
        
    }
    public class wrapperOfMap{
        
    }
    
  
}
 
<aura:component implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction"
                access="global"
                controller="dependentPicklist_UpdateCtrl">
    <!-- call doInit function on component load -->  
    <aura:handler name="init" value="this" action="{!c.doInit}"/>
    


    <!-- aura attributes-->  <!---->
    <aura:attribute name="listControllingValues" type="list" default="[]" description="to store controller field values"/>
    <aura:attribute name="listDependingValues" type="list" default="['--- None ---']" description="to store dependent field values"/>
    <aura:attribute name="listSubDependingValues" type="list" default="['--- None ---']" description="to store dependent field values"/>
    <aura:attribute name="depnedentFieldMap" type="map" description="map to store dependent values with controlling value"/>
    <aura:attribute name="SubdepnedentFieldMap" type="map" description="map to store dependent values with controlling value"/>
    <aura:attribute name="bDisabledDependentFld" type="boolean" default="true"/> 
    <aura:attribute name="bDisabledSubDependentFld" type="boolean" default="true"/> 
    
    <!--<aura:attribute name="objDetail" type="contact" default="{'sobjectType' : 'contact'}"/>-->
    <aura:attribute name="objDetail" type="ERT_Case_Type__c" default="{'sobjectType' : 'ERT_Case_Type__c'}"/>
    <aura:attribute name="controllingFieldAPI" type="string" default="Level_1__c" description="store field API name of Controller field"/>
    <aura:attribute name="dependingFieldAPI" type="string" default="Level_2__c" description="store field API name of dependent field"/>
    <aura:attribute name="subDependingFieldAPI" type="string" default="Level_3__c" description="store field API name of dependent field"/>
    
    <!--Controller Field-->
    <lightning:layoutItem size="12" padding="around-small">    
        <lightning:select name="controllerFld"
                          value="{!v.objDetail.Level_1__c}"
                           label="Country"
                          onchange="{!c.onControllerFieldChange}">
            <aura:iteration items="{!v.listControllingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
    </lightning:layoutItem>
    
    <!--Dependent Field-->
    <lightning:layoutItem size="12" padding="around-small">
        <lightning:select name="dependentFld"
                          value="{!v.objDetail.Level_2__c}"
                          label="State"
                          disabled="{!v.bDisabledDependentFld}"
                            onchange="{!c.onDepandingFieldChange}">
            <aura:iteration items="{!v.listDependingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
    </lightning:layoutItem>
        <!--SubDependent Field-->
    <lightning:layoutItem size="12" padding="around-small">
        <lightning:select name="dependentFld"
                          value="{!v.objDetail.Level_3__c}"
                          label="City"
                          disabled="{!v.bDisabledSubDependentFld}">
            <aura:iteration items="{!v.listSubDependingValues}" var="val">
                <option value="{!val}">{!val}</option>
            </aura:iteration>
        </lightning:select>
    </lightning:layoutItem>
    
</aura:component>
 
({
    doInit : function(component, event, helper) { 
        // get the fields API name and pass it to helper function  
        var controllingFieldAPI = component.get("v.controllingFieldAPI");
        var dependingFieldAPI = component.get("v.dependingFieldAPI");
        var subDepFieldAPI = component.get("v.subDependingFieldAPI"); 
        var objDetails = component.get("v.objDetail");
        // call the helper function
        helper.fetchPicklistValues(component,objDetails,controllingFieldAPI, dependingFieldAPI,subDepFieldAPI);
    },
    
    onControllerFieldChange : function(component, event, helper) {     
        var controllerValueKey = event.getSource().get("v.value"); // get selected controller field value
        var depnedentFieldMap = component.get("v.depnedentFieldMap");
         component.set("v.listSubDependingValues", ['--- None ---']);
         component.set("v.bDisabledSubDependentFld" , true);
        if (controllerValueKey != '--- None ---') {
            var ListOfDependentFields = depnedentFieldMap[controllerValueKey];
            component.set('v.SubdepnedentFieldMap',ListOfDependentFields);
             var listDepVal = []; 
            for(let depVal in ListOfDependentFields){
                  listDepVal.push(depVal);
            }
          
            if(listDepVal.length > 0){
                component.set("v.bDisabledDependentFld" , false);  
                helper.fetchDepValues(component, listDepVal,true);    
            }else{
                component.set("v.bDisabledDependentFld" , true); 
                component.set("v.listDependingValues", ['--- None ---']);
            }  
            
        } else {
            component.set("v.listDependingValues", ['--- None ---']);
            component.set("v.bDisabledDependentFld" , true);
            component.set("v.bDisabledSubDependentFld" , true);
        }
    },
    
    onDepandingFieldChange: function(component, event, helper) {   
     var depandingValueKey = event.getSource().get("v.value"); // get selected controller field value
        var depnedentFieldMap = component.get("v.SubdepnedentFieldMap");
        
        if (depandingValueKey != '--- None ---') {
            var ListOfDependentFields = depnedentFieldMap[depandingValueKey];
            console.log('ListOfDependentFields===> ' + ListOfDependentFields);
            
            var listDepVal = []; 
            for(let depVal in ListOfDependentFields){
                  listDepVal.push(ListOfDependentFields[depVal]	);
            }
          console.log('listDepVal========> ' + listDepVal);
            if(listDepVal.length > 0){
                component.set("v.bDisabledSubDependentFld" , false);  
                helper.fetchDepValues(component, listDepVal,false);    
            }else{
                component.set("v.bDisabledSubDependentFld" , true); 
                component.set("v.listSubDependingValues", ['--- None ---']);
            }  
            
        } else {
            component.set("v.listSubDependingValues", ['--- None ---']);
            component.set("v.bDisabledSubDependentFld" , true);
        }
    },
    
})
 
({
    fetchPicklistValues: function(component,objDetails,controllerField, dependentField,subDepFieldAPI) {
        // call the server side function  
        var action = component.get("c.getDependentMap");
        // pass paramerters [object definition , contrller field name ,dependent field name] -
        // to server side function 
        action.setParams({
            'objDetail' : objDetails,
            'contrfieldApiName': controllerField,
            'depfieldApiName': dependentField,
            'subDepFieldAPI' : subDepFieldAPI 
        });
        //set callback   
        action.setCallback(this, function(response) {
            alert(response.getState() == "SUCCESS");
            if (response.getState() == "SUCCESS") {
                //store the return response from server (map<string,List<string>>)  
                var StoreResponse = response.getReturnValue();
                console.log('StoreResponse===> ' + JSON.stringify(StoreResponse));
                // once set #StoreResponse to depnedentFieldMap attribute 
                component.set("v.depnedentFieldMap",StoreResponse);
                
                // create a empty array for store map keys(@@--->which is controller picklist values) 
                var listOfkeys = []; // for store all map keys (controller picklist values)
                var ControllerField = []; // for store controller picklist value to set on lightning:select. 
                
                // play a for loop on Return map 
                // and fill the all map key on listOfkeys variable.
                for (var singlekey in StoreResponse) {
                    listOfkeys.push(singlekey);
                }
                
                //set the controller field value for lightning:select
                if (listOfkeys != undefined && listOfkeys.length > 0) {
                    ControllerField.push('--- None ---');
                }
                
                for (var i = 0; i < listOfkeys.length; i++) {
                    ControllerField.push(listOfkeys[i]);
                }  
                // set the ControllerField variable values to country(controller picklist field)
                component.set("v.listControllingValues", ControllerField);
            }else{
                alert('Something went wrong..');
            }
        });
        $A.enqueueAction(action);
    },
    
    fetchDepValues: function(component, ListOfDependentFields,hasDepandingList) {
        // create a empty array var for store dependent picklist values for controller field  
        var dependentFields = [];
        dependentFields.push('--- None ---');
        for (var i = 0; i < ListOfDependentFields.length; i++) {
            dependentFields.push(ListOfDependentFields[i]);
        }
        // set the dependentFields variable values to store(dependent picklist field) on lightning:select
        if(hasDepandingList){
             component.set("v.listDependingValues", dependentFields);
        }
        else {
             component.set("v.listSubDependingValues", dependentFields);
        }
       
        
    },
    
})

let me  know it's  working or not. and try this code on another object.
wating of your  response
Thank you
This was selected as the best answer