Thursday, December 19, 2019

How to cover the Approval Process in test class in Salesforce

# Approach 1

Ex: you have an approval process on an opportunity when the amount is greater than 500 the opportunity requires an approval.
Create the opportunity test data as per the approval process criteria and query the process instance object data and use the assert methods to verify the values.

Sample Code
Opportunity objOpp = new Opportunity(Name = 'Test Opp', amount = 800);
insert objOpp;

ProcessInstance objProcessInstance = [SELECT Id,TargetObjectId, CreatedDate FROM ProcessInstance WHERE TargetObjectId = :objOpp.Id];
System.assertEquals(objOpp.CreatedDate,objProcessInstance.CreatedDate);

# Approach 2

Create the Opportunity test data and submit the Opportunity for the approval process using the ProcessSubmitRequest method.

Sample Code
Opportunity objOpp = new Opportunity(Name = 'Test Opp', amount = 500);
insert objOpp;

Approval.ProcessSubmitRequest app = new Approval.ProcessSubmitRequest();
app.setObjectId(objOpp.id);
Approval.ProcessResult result = Approval.process(app);

Tuesday, December 17, 2019

How to get Custom Metadata Type data without Apex in Lightning Web Components(lwc)

What is Custom Metadata Type in Salesforce?
Custom metadata are like custom settings but records in custom metadata type considered as metadata rather than data.
These are typically used to define application configurations that need to be migrated from one environment to another, or packaged and installed.

You cannot perform CUD (Create, Update, Delete) operation on custom metadata type in apex.

Custom Metadata Type object suffix with __mdt

Normally in apex, we are using SOQL query to get the Custom metadata type data.

How to get the Custom Metadata Type data in Lightning web components?

To get the Custom metadata type data in the lightning web component you can use the wire service to get record data. To get the data, the Lightning Web Component uses the getRecord wire adapter.

Syntax
import { getRecord } from 'lightning/uiRecordApi';

For the demo, I created the Country and Amount(Country_And_Amount__mdt) Custom Metadata type object and records.

Country_And_Amount__mdt object


Country_And_Amount__mdt records



HTML Code
<template>
    <lightning-card title="Custom Metadata Types Record Values">
        <template if:true={objMetadataValues}>
            <dl class="slds-list_horizontal slds-wrap" style="margin-left: 3%;">
                <dt class="slds-item_label slds-truncate" title="First Name">Master Label</dt>
                <dd class="slds-item_detail slds-truncate"><b>{objMetadataValues.MasterLabel}</b></dd>
                <dt class="slds-item_label slds-truncate" title="Last Name">Developer Name:</dt>
                <dd class="slds-item_detail slds-truncate"><b>{objMetadataValues.DeveloperName}</b></dd>
                <dt class="slds-item_label slds-truncate" title="Full Name">Amount:</dt>
                <dd class="slds-item_detail slds-truncate"><b>{objMetadataValues.Amount}</b></dd>
            </dl>
        </template>
    </lightning-card>
</template>

Javascript Controller
import { LightningElement, track, wire} from 'lwc';

// import to get the record details based on record id
import { getRecord } from 'lightning/uiRecordApi';

export default class metadataDetailsInLWC extends LightningElement {

    @track objMetadataValues = {};
    
    // using wire service getting current user data
    // HardCoded the Record Id you can dynamically pass the record id using track or api decorates
    @wire(getRecord, { recordId: 'm02B00000006hGx', fields: ['Country_And_Amount__mdt.MasterLabel', 'Country_And_Amount__mdt.DeveloperName', 'Country_And_Amount__mdt.Amount__c'] })
    userData({error, data}) {
        if(data) {
            let currentData = data.fields;
            this.objMetadataValues = {
                MasterLabel : currentData.MasterLabel.value,
                DeveloperName: currentData.DeveloperName.value,
                Amount: currentData.Amount__c.value

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

}

Output

Monday, December 16, 2019

Use of VisualforceAccessMetrics object in the Salesforce

This object is used to query the metrics of the visualforce page in your org.
Using VisualforceAccessMetrics, you can track the number of views each Visualforce page in your org receives in a 24-hour time period. To find out how many views a page got over the course of multiple days, you can query multiple VisualforceAccessMetrics objects for the same ApexPageId.

Page views are tallied the day after the page is viewed, and each VisualforceAccessMetrics object is removed after 90 days.

To get the metrics of the visualforce page data, make a SOQL query in Workbench to get information from the VisualforceAccessMetrics object.

1. Log in to Workbench.
2. Select production/sandbox.
3. select 'SOQL Query'.

SOQL Query
SELECT ApexPageId, DailyPageViewCount, Id, ProfileId, MetricsDate, LogDate FROM VisualforceAccessMetrics

Output

Sunday, December 15, 2019

Recycle Bin in Salesforce Lightning Experience

In 'Winter 20' salesforce releases the Recycle bin for Lightning Experience.

Recycle bin contains all the features like list view, Delete, restore, empty recycle bin.

Wednesday, December 11, 2019

How to disable task notification when task is assigned to the user in salesforce

Go the user personal settings, enter Activity Reminders in the Quick Find box, then select Activity Reminders.
Deselect Email me when someone assigns me a task.


Monday, December 2, 2019

How to make default Landing Page as Setup page in Salesforce

To make the default landing page as setup page, go to the 'Advanced User Details' of the user and enable the 'Make Setup My Default Landing Page' permission.


Sunday, December 1, 2019

How to get Picklist values based on record type in Lightning Web Components(lwc)

To get picklist values based on record type we have to use getPicklistValuesByRecordType wire adapter.
Syntax
import { getPicklistValuesByRecordType } from 'lightning/uiObjectInfoApi';

In this demo, I am using Account object, based on record type id I am getting picklist values of Industry field

HTML Code
<template>
    <lightning-card title="Picklist Vlaues based on Record Type">
      <div if:true={options}>
            <lightning-combobox name="progress"
                                label="Industry"
                                value={value}
                                placeholder="-Select-"
                                options={options}
                                onchange={handleChange} ></lightning-combobox><br/>
        
            you selected industry: <b>{value}</b><br/><br/>
      </div>
    </lightning-card>
    
</template>

Javascript Controller
import { LightningElement, track, wire} from 'lwc';
import { getPicklistValuesByRecordType } from 'lightning/uiObjectInfoApi';

export default class PicklistValuesByRecordType extends LightningElement {
    @track value;
    @track options;

    @wire(getPicklistValuesByRecordType, { objectApiName: 'Account', recordTypeId: '012B0000000gTUOIA2' }) 
    IndustryPicklistValues({error, data}) {
        if(data) {
            this.options = data.picklistFieldValues.Industry.values;
        }
        else if(error) {
            window.console.log('error =====> '+JSON.stringify(error));
        }
    }

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

Output

Saturday, November 30, 2019

How to remove ‘noreply@salesforce.com on behalf of’ on email sent from salesforce

Salesforce automatically adds the "no-reply@Salesforce.com on behalf of" to the sender field on emails sent from Salesforce.
To remove the "no-reply@Salesforce.com on behalf of" we have to deselect the "Enable Sender ID compliance" permission in email delivery setting.

Path:
From Setup, enter Email Administration(Classic) || Email(Lightning Experience) in the Quick Find box, and then Deliverability
Under the Email Security Compliance section, Deselect the Enable Sender ID compliance box and then click Save.


Monday, November 25, 2019

Undelete trigger event in apex trigger in Salesforce


Before Undelete

The record is available, but the field isDeleted set to True. the before undelete trigger wouldn’t be able to see the records(values) that it needs. due to this reason, there is no before undeleting operation available.

After undelete

The after undelete trigger event only works with recovered records—that is, records that were deleted and then recovered from the Recycle Bin through the undelete DML statement. These are also called undeleted records.

Ex:
If you delete an Account, an Opportunity may also be deleted. When you recover the Account from the Recycle Bin, the Opportunity is also recovered.
If there is an after undelete trigger event associated with both the Account and the Opportunity, only the Account after undelete trigger event executes.

The after undelete trigger event only fires for the following objects:

  • Account
  • Asset
  • Campaign
  • Case
  • Contact
  • ContentDocument
  • Contract
  • Custom objects
  • Event
  • Lead
  • Opportunity
  • Product
  • Solution
  • Task

Tuesday, November 19, 2019

How to get recently viewed information of user in org using SOQL

Salesforce stores the recently viewed information in RecentlyViewed object
RecentlyViewed represents records that the current user has recently viewed or referenced (by viewing a related record).

If you want to query the multiple sObject records recently viewed information.
Ex: I want to see the recently viewed account and contact records in org.
Select Id, Name, Type, LastViewedDate, Profile.Name FROM RecentlyViewed WHERE Type IN ('Account', 'Contact') ORDER BY LastViewedDate DESC



You can also use the LastViewdDate field on the sObject. 
Ex: I want to see only recently viewed Account records.
SELECT Id, Name, LastViewedDate FROM Account WHERE LastViewedDate != NULL ORDER BY LastViewedDate DESC limit 5


Resource
RecentlyViewed Object

Monday, November 18, 2019

How to deploy custom metadata type using ANT tool in Salesforce

Use the below package.xml to retrieve/deploy the custom metadata type using ANT tool
Custom metadata type is like custom object but you have use __mdt
Ex: custommetdatatypename__mdt

package.xml
<!-- Custom Metadata Type -->  
<types>  
    <members>CustomMetadataAPIname__mdt</members>  
    <name>CustomObject</name>  
</types>  

<!-- Custom Metadata Type records/data-->  
<types>  
    <members>CustomMetadata__mdt.RecordName</members>  
    <name>CustomMetadata</name>  
</types>  
 


Tuesday, November 12, 2019

How to get Record Id and Object Name into Lightning Web Component(lwc)

We used the force:hasRecordId interface to a Lightning component to enable the component to be assigned the ID of the current record. The current record ID is useful if the component is used on a Lightning record page.

We used the force:hasSObjectName interface to a Lightning component to enable the component to be assigned the API name of the current record’s sObject type. The sObject name is useful if the component can be used with records of different sObject types.

To get the record id and sObjectName in Lightning web components we can use the public decorate '@api'
@api recordId;
@api objectApiName;

HTML Code
<template>
    <lightning-card>
        <div class="slds-text-heading_medium slds-text-align_center">
            Record Id : {currenRecordId}
        </div>
        <div class="slds-text-heading_medium slds-text-align_center">
            Object Name : {currenObjectName}
        </div>
    </lightning-card>
</template>

Javascript Controller
import { LightningElement, api, track } from 'lwc';

export default class LWCDemo extends LightningElement {
    @api objectApiName;
    @api recordId;
    @track currenObjectName;
    @track currenRecordId;

    connectedCallback() {
        this.currenRecordId = this.recordId;
        this.currenObjectName = this.objectApiName;
    }
}
Configuration File
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="LWCDemo">
    <apiVersion>46.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
    </targets>
</LightningComponentBundle>

Output

Saturday, November 9, 2019

Convert Attachment to File in Salesforce Using Apex

Note:
If you want to modify System audit Fields like CreatedDate, CreatedById, etc fields while converting to file. you must have the below permission "Set Audit Fields upon Record Creation" and "Update Records with Inactive Owners" 


How to Enable?

Path:
From Setup, enter User Interface in the Quick Find box, and then select "Set Audit Fields upon Record Creation" and "Update Records with Inactive Owners" 


Activating this feature in User Interface allows you to grant permission to set audit fields and update records with inactive owners, but it does not grant the permission by default.
You will need to grant the following profile permissions to your Users(Who are converting to file)

Set Audit Fields upon Record Creation - Allow the User to set audit fields (like 'Created By' or 'Last Modified By') when you create a record via API importing tools like Data Loader.
Update Records with Inactive Owners - Allow the User to update record owner and sharing-based records with inactive owners.

Add a permission set

1. Navigate to Setup.
2. Quick Find 'Permission Set'.
3. Click New.
4. Enter the name of the permission set.
5. Under System Permissions, grant any of the 2 permissions:
    i. Set Audit Fields upon Record Creation
    ii. Update Records with Inactive Owners
6. Click Save.
7. Click Manage Assignments.
8. Search for the name of the Users that will need the permission.
9. Click Add Assignment.

After you have permission now you are ready to convert the file.

Sample Code
list<ContentVersion> lstCntVersionsToInsert = new list<ContentVersion>();
list<Attachment> lstAttachments = [SELECT Id, ParentId, Name, IsPrivate, Body, OwnerId, CreatedById, CreatedDate, Description FROM Attachment where ParentId != null];
for(Attachment attIterator : lstAttachments) {
 ContentVersion objCntVersion = new ContentVersion();
 objCntVersion.Title = attIterator.Name;
 objCntVersion.PathOnClient = '/' + attIterator.Name;
 objCntVersion.VersionData = (attIterator.Body == null ? Blob.valueOf('.') : attIterator.Body);
 objCntVersion.Description = attIterator.Description;
 objCntVersion.SharingPrivacy = 'N'; // Can be always public.
 objCntVersion.FirstPublishLocationId = attIterator.ParentId; // Parent Id
 objCntVersion.OwnerId = attIterator.OwnerId;
 // To avoid "Documents in a user's private library must always be owned by that user" error.
 objCntVersion.CreatedById = attIterator.OwnerId; 
 objCntVersion.CreatedDate = attIterator.CreatedDate;
 objCntVersion.FirstPublishLocationId = attIterator.OwnerId;
 lstCntVersionsToInsert.add(objCntVersion);
}

if(!lstCntVersionsToInsert.isEmpty()) {
    insert lstCntVersionsToInsert;
}

How to retrieve Lightning Web Components Using ANT tool

To retrieve the Lightning web components use new Metadata API component is called LightningComponentBundle

Package.xml
<types>
    <members>*</members>
    <name>LightningComponentBundle</name>
</types>


Reference
LightningComponentBundle

Friday, November 8, 2019

How to Get the Session Id of Current User in Lightning Development



You may be faced with Error is "errorCode": "INVALID_SESSION_ID"  while doing the external web services and internal salesforce API Callouts with Salesforce in lighting development.

The session id can be fetched through UserInfo.getSessionId() method in apex but which is not available lightning context.
you can use the below solution it will resolve the error.

Visualforce Page
<apex:page contentType="application/json">
    {!$Api.Session_ID}
</apex:page>

Apex Class
public class SessionIdController {
 public static String getSessionId() {
        return Page.GenerateSessionIdForLWC.getContent().toString();
    }
}

simply use the Apex method where you need to the Session-Id.

lightning Button group in Lightning web component(lwc)

HTML Code
<template>
    <lightning-card>
    <div class="slds-m-top_medium slds-m-bottom_x-large">
        <h2 class="slds-text-heading_medium slds-m-bottom_medium">
            Simple Button group using lightning buttons.
        </h2>
        <lightning-button-group>
            <lightning-button label="Refresh" onclick={handleButtonGroup}></lightning-button>
            <lightning-button label="Edit" onclick={handleButtonGroup}></lightning-button>
            <lightning-button label="Save" onclick={handleButtonGroup}></lightning-button>
        </lightning-button-group><br/><br/>

        <p>You clicked on <b>{value}</b> button</p>
    </div>
    </lightning-card>
</template>

Javascript Controller
import { LightningElement, track } from 'lwc';

export default class ButtonGroupBasic extends LightningElement {
    @track value;
    handleButtonGroup(event) {
        console.log('label ===> '+event.target.label);
        this.value = event.target.label;
    }
}

Output

How to get available Lightning Components In your org

Note: My domain should be enabled in your org

  • Login to your org 
  • Add componentReference/suite.app in your org domain URL
Ex:
https://<yourorgdomain>.lightning.force.com/componentReference/suite.app

you can see all the available components of your Org along with Salesforce Lightning Component and Lightning web components examples.


Thursday, November 7, 2019

Calculate number of years between two dates in salesforce using apex

Sample Code
Date dtToday = Date.today();
Date dtOther = Date.today().addMonths(50);
system.debug('Number of months  ===> ' + dtToday.monthsBetween(dtOther));
String strNoOfYears = String.valueOf(dtToday.monthsBetween(dtOther) / 12) + ' Year(s) ' + String.valueOf(Math.mod(dtToday.monthsBetween(dtOther), 12)) + ' Month(s)';
system.debug('Difference b/w two dates ====>  ' + strNoOfYears);

Result

Saturday, November 2, 2019

Lightning Formatted Address component in Lightning Web Component(lwc)

We can show the formatted address using the lightning-formatted-address component in a lightning web component.
This example shows how to use the lightning-formatted-address
Ex:
HTML Code
<template>
    <lightning-card>
        <lightning-formatted-address city={accCity} 
                                     country={accCountry} 
                                     postal-code={accPostalcode} 
                                     province={accState} 
                                     street={accStreet}
                                     show-static-map={showStaticMap}></lightning-formatted-address>
    </lightning-card>
</template>
Javascript Controller
import { LightningElement, api, wire, track} from 'lwc';
import { getFieldValue, getRecord } from 'lightning/uiRecordApi';
import ACC_BillingCity from '@salesforce/schema/Account.BillingCity';
import ACC_BillingStreet from '@salesforce/schema/Account.BillingStreet';
import ACC_BillingState from '@salesforce/schema/Account.BillingState';
import ACC_BillingPostalCode from '@salesforce/schema/Account.BillingPostalCode';
import ACC_BillingCountry from '@salesforce/schema/Account.BillingCountry';

export default class formatAddressComponent extends LightningElement {
    // recordId value provided by Account record page
    @api recordId;
    @track showStaticMap = true;
    @wire(getRecord, { recordId: '$recordId', fields: [ACC_BillingCity, ACC_BillingStreet, ACC_BillingState, ACC_BillingPostalCode, ACC_BillingCountry]})
    account;


    get accStreet() { 
        window.console.log('accpount ===> '+JSON.stringify(this.account.data))
        return getFieldValue(this.account.data, ACC_BillingStreet)
    }

    get accCity() { 
        return getFieldValue(this.account.data, ACC_BillingCity)
    }

    get accCountry() { 
        return getFieldValue(this.account.data, ACC_BillingCountry)
    }

    get accState() { 
        return getFieldValue(this.account.data, ACC_BillingState)
    }

    get accPostalcode() { 
        return getFieldValue(this.account.data, ACC_BillingPostalCode)
    }
}

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

Output


Friday, November 1, 2019

Reusable Picklist in Salesforce using Lightning web components(lwc)

This post explains how to implement reusable picklist in the lightning web component(lwc)


To get the picklist values in lightning web components we can use 'getPicklistValues' or 'getPicklistValuesByRecordType' wire adapters, these wire adapters uses the lightning/uiObjectInfoApi scoped module to get the picklist values based on specific Field or based on Record Type.

HTML Code
<template>
    <lightning-combobox label={picklistlabel} 
                        name={picklistlabel} 
                        onchange={handleValueChange} 
                        options={options} 
                        placeholder="--None--" 
                        value={selectedValue}></lightning-combobox>
    <div if:true={error} style="margin-left:3%">
        <b style="color: red;">{error}</b>
    </div>
</template>
Javascript Controller
import {LightningElement, api, track, wire} from 'lwc';
import {getPicklistValues, getObjectInfo} from 'lightning/uiObjectInfoApi';

export default class Reusepicklistinlwc extends LightningElement {
    @api objAPIName;
    @api fieldAPIName;
    @track options = [];
    // pick list label
    @track picklistlabel;
    @track error;

    recordTypeId;
    objfieldAPIName;

    @wire(getObjectInfo, {objectApiName: '$objAPIName'})
    objectInfo(result) {
        if(result.data) {
            // Field Data
            let fieldData = result.data.fields[this.fieldAPIName];
            if(fieldData) {
                this.picklistlabel = fieldData.label;
            
                this.objfieldAPIName = {};
                this.objfieldAPIName.fieldApiName = fieldData.apiName;
                this.objfieldAPIName.objectApiName = result.data.apiName;
    
                this.recordTypeId = result.data.defaultRecordTypeId;
            }
            else {
                this.error = 'Please enter valid field api name';
            }
        }
        else if(result.error) {
            this.error = JSON.stringify(result.error);
        }
    }
    
    @wire(getPicklistValues, { recordTypeId: '$recordTypeId', fieldApiName: '$objfieldAPIName'})
    picklistValues({error, data}) {
        if (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) {
            this.error = JSON.stringify(error);
        }
    }


    handleValueChange(event) {
        this.selectedValue = event.target.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>
</LightningComponentBundle>

How to use the component

Add this component in your parent component and pass object API name and field API name

Ex:
<template>
    <lightning-card>
        <!-- Account Type picklist -->
        <c-reusepicklistinlwc field-a-p-i-name="Type" obj-a-p-i-name="Account"></c-reusepicklistinlwc>
        <!--Contact Lead source picklist-->
        <c-reusepicklistinlwc field-a-p-i-name="LeadSource" obj-a-p-i-name="Contact"></c-reusepicklistinlwc>
    </lightning-card>
</template>

Saturday, October 26, 2019

Custom Dependent Picklist Field in Salesforce using Lightning Web Components

This post explains how to implement custom dependent picklist field using lightning web components(lwc)



To get the picklist values in lightning web components we can use 'getPicklistValues' or 'getPicklistValuesByRecordType' wire adapters, these wire adapters uses the lightning/uiObjectInfoApi scoped module to get the picklist values based on specific Field or based on Record Type.

Syntax

import { getPicklistValues, getPicklistValuesByRecordType } from 'lightning/uiObjectInfoApi';

For the demo, I created two fields on Account.
Controlling Field(picklist): Account Country
Dependent Field(picklist): Account State

The structure of the dependent field


HTML Code
<template>
    <lightning-card title="Custom Dependent Picklist using Lightning Web Components"><br/>
        <div class="slds-grid slds-gutters" style="margin-left:3%">
            <div class="slds-col slds-size_1-of-4">
                <lightning-combobox label="Account Country" 
                                    name="country" 
                                    onchange={handleCountryChange} 
                                    options={controllingValues} 
                                    placeholder="--None--" 
                                    value={selectedCountry}></lightning-combobox><br/>
                
                <div if:true={selectedCountry}>
                    Selected Country: <b>{selectedCountry}</b>
                </div>
            </div>
            <div class="slds-col slds-size_1-of-4">
                <lightning-combobox label="Account State" 
                                    name="state"
                                    onchange={handleStateChange} 
                                    options={dependentValues} 
                                    placeholder="--None--" 
                                    value={selectedState}
                                    disabled={isEmpty}></lightning-combobox><br/>
                <div if:true={selectedState}>
                    Selected State: <b>{selectedState}</b>
                </div>
            </div>
        </div><br/>

        <div if:true={error}>
            <p>{error}</p>
        </div>
    </lightning-card>
</template>

Javascript Controller Code
import { LightningElement, wire, track } from 'lwc';
import { getPicklistValuesByRecordType } from 'lightning/uiObjectInfoApi';
import { getObjectInfo } from 'lightning/uiObjectInfoApi';
import ACCOUNT_OBJECT from '@salesforce/schema/Account';

export default class DependentPickListInLWC extends LightningElement {

    // Reactive variables
    @track controllingValues = [];
    @track dependentValues = [];
    @track selectedCountry;
    @track selectedState;
    @track isEmpty = false;
    @track error;
    controlValues;
    totalDependentValues = [];

    // Account object info
    @wire(getObjectInfo, { objectApiName: ACCOUNT_OBJECT })
    objectInfo;

    // Picklist values based on record type
    @wire(getPicklistValuesByRecordType, { objectApiName: ACCOUNT_OBJECT, recordTypeId: '$objectInfo.data.defaultRecordTypeId'})
    countryPicklistValues({error, data}) {
        if(data) {
            this.error = null;

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

            // Account Country Control Field Picklist values
            data.picklistFieldValues.Account_Country__c.values.forEach(key => {
                countyOptions.push({
                    label : key.label,
                    value: key.value
                })
            });

            this.controllingValues = countyOptions;

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

             // Account State Control Field Picklist values
            this.controlValues = data.picklistFieldValues.Account_State__c.controllerValues;
            // Account State dependent Field Picklist values
            this.totalDependentValues = data.picklistFieldValues.Account_State__c.values;

            this.totalDependentValues.forEach(key => {
                stateOptions.push({
                    label : key.label,
                    value: key.value
                })
            });

            this.dependentValues = stateOptions;
        }
        else if(error) {
            this.error = JSON.stringify(error);
        }
    }

    handleCountryChange(event) {
        // Selected Country Value
        this.selectedCountry = event.target.value;
        this.isEmpty = false;
        let dependValues = [];

        if(this.selectedCountry) {
            // if Selected country is none returns nothing
            if(this.selectedCountry === '--None--') {
                this.isEmpty = true;
                dependValues = [{label:'--None--', value:'--None--'}];
                this.selectedCountry = null;
                this.selectedState = null;
                return;
            }

            // filter the total dependent values based on selected country value 
            this.totalDependentValues.forEach(conValues => {
                if(conValues.validFor[0] === this.controlValues[this.selectedCountry]) {
                    dependValues.push({
                        label: conValues.label,
                        value: conValues.value
                    })
                }
            })

            this.dependentValues = dependValues;
        }
    }

    handleStateChange(event) {
        this.selectedState = event.target.value;
    }
}

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

You can also find the code on Github
GitHub Link


Result