Friday, 15 November 2019

Salesforce Virtual Dreamin

Virtual Dreamin

We are glad to announce the world first Salesforce Virtual Dreamin after a great success of Apex Hours, Automation Champion and Path To Code virtual program. All these events got fantastic response from various part of globe because it can be attended by anyone from anywhere.

This Idea and huge response from audience, on how convenient it is to join conference or remote meetings inspired the idea of First Salesforce Virtual Dreamin.

"Geographical location is not an obstacle anymore. Join Dreamin from anywhere on planet"

Virtual Dreamin would be running for 24 hours for 2 days, so that everyone would get chance to join sessions in their timezone. Save the date Feb 22-23 2020 and follow us on Virtual Dreamin Website for more detail.

Virtual Dreamin is focused for all audiences who wants to start or advance their career in Salesforce. All the session will focus on all below track
  1. System Admin
  2. Salesforce Developer
  3. Architect

FAQ
  1. What is Virtual Dreamin ?
    This is a community driven event for community. Where we will joins lots of Virtual Salesforce sessions.
  2. Who Can Attend?
    Any one who want to become Salesforce Admin, Salesforce Developer or Salesforce Architect.
  3. Why Should I Attend ?
    You get to witness inspiring keynotes and sessions by some of the best from Salesforce.
  4. How to register ?
  5. What is the registration fee ?
    Free, Yes this is free event which you can join from your home or office. You only need one good Internet Speed.

Follow us
  1. Facebook
  2. Twitter

Please share your feedback and let us know what you want to learn in Virtual Dreamin


Thanks,
Amit Chaudhary
Founder of ApexHours and Virtual Dreamin.
Salesforce MVP

Friday, 8 November 2019

Import and Export Data using SalesforceDX (SFDX)

Import and Export Data using SalesforceDX (SFDX)


In this post we will talk about Data migration using SalesforceDX. We have a vary simple use case to Import and Export data from one Salesforce Org to another Salesforce Org. We know we can do the same with dataloader or some other custom tool. But in this post we will talk about how to import and export with SalesforceDX (SFDX). If you are new to SalesforceDx please check this ApexHours Session Recording by Jitender Zaa.


How to export records with SFDX


 Step 1) First Login to your Salesforce Org from where you want to export data

sfdx force:auth:web:login --setalias myDev1

Step 2) Use below command to export the data

To Export the data we need to use "sfdx force:data:tree:export" command and we need to pass one Soql query. You can also pass the path of SOQL query file with the help of -q. Lets export the Account and its all related contacts records.

sfdx force:data:tree:export -q "SELECT Id,Name,(Select FirstName,LastName from Contacts) FROM Account limit 2" -d ./data -p -u myDev1

Here
-q : SOQL query or file path of soql query.
-d : directory, where exported json file can be saved
-u : Salesforce user to perform operation
-p : generate multiple sobject tree files and a plan definition file for aggregated import


Once you execute above command it will create three file for you in Data Folder.
  • Accounts.json
  • Contacts.json
  • Account-Contact-plan.json

How to Import data using Salesforce DX


First login to salesforce org in which you want to import the data. Then use below command to Import records in Salesforce instance, which we just exported in previous step

sfdx force:data:tree:import -p data/Account-Contact-plan.json -u myDev1

Where
-f : JSON file to be imported
-p : plan file
-u : Salesforce user to perform operation

The query for export can return a maximum of 2,000 records. For more information, see the REST API Developer Guide:
 

NOTE: For above use case you don't need any scratch org. You can simply login in any sandbox and migrate your data between two org's.


There is another Use case where we can use SalesforceDx for Import and Export Data.

Use Case: If you are implementing Continuous Integration (CI/CD) solution built for Salesforce, Some time you need to upload sample data into Salesforce.

Solution: For that you need to use command line dataloader or custom tool built to import export data automatically. We can use SalesforceDX for data import and export as well for this requirement.


Related Post :



Further Reading:

Thanks,
Amit Chaudhary

Friday, 18 October 2019

Lightning Message Service (LMS) | MessageChannel

In Winter 20 Salesforce Introduce the new feature Lightning Message Service. Lightning Message Service (LMS) allow you to communicate between Visualforce and Lightning Components (Aura and LWC both) on any Lightning page. LMS API allow you to publish message throughout the lightning experience and subscribe the same message anywhere with in lightning page. It is similar to Aura Application Events to communication happens between components.


Lightning Message Service is based on a new metadata type: Lightning Message Channels. We need to use Lightning Message Channel to access the Lightning Message Service API.
  1. In LWC we can access Lightning Message Channel with the scoped module @salesforce/messageChannel
  2. In Visualforce, we can use global variable $MessageChannel
  3. In Aura, use lightning:messageChannel in your component

 

When to use Lightning Message Service. 

In Lightning Experience, if we want a Visualforce page to communicate with a Lightning web component then we have to implement a custom publish-subscribe solution because this is currently not possible with LWC Event. Now, we can use the Lightning Message Service API to handle this communication.
Lightning Message Service LMS and Message Channel


Let see how we can implements this

Create Lightning Message Channel :-

Currently we can create Lightning Message channel with Metadata API. You can create the same with the help of VsCode. I hope you have VsCode installed in your machine if not please check this post. You need to create one DX project then you need to place your message channel definition with the suffix .messageChannel-meta.xml in the force-app/main/default/messageChannels directory. like below folder structure.

MyMessageChannel.messageChannel-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningMessageChannel xmlns="http://soap.sforce.com/2006/04/metadata">
   <masterLabel>MyMessageChannel</masterLabel>
   <isExposed>true</isExposed>
   <description>This Lightning Message Channel sends information from VF to LWC</description>

   <lightningMessageFields>
       <fieldName>messageToSend</fieldName>
       <description>message To Send</description>
   </lightningMessageFields>

   <lightningMessageFields>
       <fieldName>sourceSystem</fieldName>
       <description>My source?</description>
   </lightningMessageFields>

</LightningMessageChannel>

And Package.xml should be like below
package.xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Package xmlns="http://soap.sforce.com/2006/04/metadata">
    <types>
       <members>*</members>
       <name>LightningMessageChannel</name>
    </types>
    <version>47.0</version>
</Package>
Right click on LightningMessageChannel file and Deploy in Org.

 

Create Visualforce page and LWC

 

1) LMS with Visualforce page

Salesforce introduced new sforce.one APIs — publish, subscribe, and unsubscribe — in Visualforce to interact with LMS (only available in Lightning).

LMSVisualforcePage.page
<apex:page>
  
    <div>
        <p>Enter Your Message Here:</p>
        <input type="text" id="theMessage" />
        <button onclick="publishMC()"> Publish Msg</button>
        <br/><br/>
            <button onclick="subscribeMC()">Subscribe</button>
            <button onclick="unsubscribeMC()">Unsubscribe</button>
        <br/>
        <br/>
        <p>Received message:</p>
        <label id="MCMessageText"/>
    </div>
  
    <script>
      
        // Load the MessageChannel token in a variable
        var SAMPLEMC = "{!$MessageChannel.MyMessageChannel__c}";
        var subscriptionToMC;

        function publishMC() {
            const message = {
                messageToSend: document.getElementById('theMessage').value,
                sourceSystem: "From VisualForce Page"
            };
            sforce.one.publish(SAMPLEMC, message);
        }
      
        // Display message in the textarea field
        function displayMessage(message) {
            var textLabel = document.querySelector("#MCMessageText");
            textLabel.innerHTML = message ? JSON.stringify(message, null, '\t') : 'no message payload';
        }

        function subscribeMC() {
            if (!subscriptionToMC) {
                subscriptionToMC = sforce.one.subscribe(SAMPLEMC, displayMessage);
            }
        }

        function unsubscribeMC() {
            if (subscriptionToMC) {
                sforce.one.unsubscribe(subscriptionToMC);
                subscriptionToMC = null;
            }
        }

    </script>

</apex:page>

  • "subscribeMC" method is used to subscribe the Message Channel with "sforce.one.subscribe(SAMPLEMC, displayMessage);"
  • "unsubscribeMC" method to unsubscribe the Message Channel with "sforce.one.unsubscribe(subscriptionToMC);"
  • "publishMC" to publish the message withe the help of "sforce.one.publish(SAMPLEMC, message);"

2) LMS with Lightning Web Components

lMCWebComponentDemo.js
import { LightningElement,track } from 'lwc';
import { publish,subscribe,unsubscribe,createMessageContext,releaseMessageContext } from 'lightning/messageService';
import SAMPLEMC from "@salesforce/messageChannel/MyMessageChannel__c";

export default class LMCWebComponentDemo extends LightningElement {
    @track receivedMessage = '';
    @track myMessage = '';
    subscription = null;
    context = createMessageContext();

    constructor() {
        super();
    }

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

    publishMC() {
        const message = {
            messageToSend: this.myMessage,
            sourceSystem: "From LWC"
        };
        publish(this.context, SAMPLEMC, message);
    }

    subscribeMC() {
        if (this.subscription) {
            return;
        }
        this.subscription = subscribe(this.context, SAMPLEMC, (message) => {
            this.displayMessage(message);
        });
     }
 
     unsubscribeMC() {
         unsubscribe(this.subscription);
         this.subscription = null;
     }

     displayMessage(message) {
         this.receivedMessage = message ? JSON.stringify(message, null, '\t') : 'no message payload';
     }

     disconnectedCallback() {
         releaseMessageContext(this.context);
     }

}
  • First, we have to ensure that we import both the methods to interact with LMS
    import { publish,subscribe,unsubscribe,createMessageContext,releaseMessageContext } from 'lightning/messageService';
    import SAMPLEMC from "@salesforce/messageChannel/MyMessageChannel__c";

lMCWebComponentDemo.html
<template>
    <lightning-card title="LMC Web Component" icon-name="custom:custom14">
        <div class="slds-m-around_medium">
            <p>MessageChannel: MyMessageChannel__c</p>
            <br>
        </div>
        <!-- Default/basic -->
        <div class="slds-p-around_medium lgc-bg">
            <lightning-input type="text" label="Enter some text" value={myMessage} onchange={handleChange}></lightning-input>
            <lightning-button label="Publish" onclick={publishMC}></lightning-button>
        </div>

        <div class="slds-p-around_medium lgc-bg">
            <lightning-button label="Subscribe" onclick={subscribeMC}></lightning-button>
            <lightning-button label="Unsubscribe" onclick={unsubscribeMC}></lightning-button>
            <p>Latest Message Received</p>
            <lightning-formatted-text value={receivedMessage}></lightning-formatted-text>
        </div>

    </lightning-card>
</template>


Reference:

Some other related post:
  1. Event Communication in Lightning Web Components
  2. Event Communication in Lightning Components
  3. Setup VsCode for Salesforce
  4. Lightning We Components

Thanks
Amit Chaudhary


Thursday, 17 October 2019

Lightning datatable In Lightning Web Components | lightning datatable inline edit

Welcome back, In this post we are going to create another lightning web component (LWC), Where we can search contact records and will display result using lightning-datatable lwc component. Lightning datatable tag is same as lightning:datatable tag in aura. In this lightning Datatable example we will also talk about lightning datatable inline edit.

lighning-datatable syntax:-
                    <lightning-datatable key-field="Id" 
                                            data={contacts} 
                                            columns={columns} 
                                            hide-checkbox-column="true" 
                                            show-row-number-column="true"
                                            > 
                    </lightning-datatable> 
  • If you want to hide the checkbox from table then add "hide-checkbox-column"
  • If you want to show row number then please add "show-row-number-column".
Let's see how we can create custom record search functionality in lightning web components. I hope VsCode is already setup on you machine and you know how to create Lightning Web Component. If not please check this post.

1) Create Apex Class

public with sharing class LWCDataTableExample {
    @AuraEnabled(Cacheable=true)
    public static List <Contact> getContacts(String strLastName) {
        String strLastNameLike = '%'+strLastName+'%';
        List<Contact> contList = [SELECT Id,FirstName,LastName,Account.Name
                                   FROM Contact
                                   Where LastName like :strLastNameLike
                                   LIMIT 10];
        return contList;
    }   
}

This apex class we will call from Lightning web components. If you want to learn more about how to call apex class from lightning web components then please check this post.

2) Create Lightning Web Components.

lwcLightningDataTableDemo.html
<template>
    <lightning-card title = "Search Contacts" icon-name = "custom:custom63"> 
        <div class = "slds-m-around_medium"> 
            <lightning-input type = "search" onchange = {handleKeyChange} class = "slds-m-bottom_small" label = "Search" >
            </lightning-input> 
            <template if:true = {contacts}> 
                <div style="height: 300px;"> 
                    <lightning-datatable key-field="Id" 
                                            data={contacts} 
                                            columns={columns} 
                                            hide-checkbox-column="true" 
                                            show-row-number-column="true"> 
                    </lightning-datatable> 
                </div>                  
            </template>
            <template if:true = {error}> 
                {error}> 
            </template> 
        </div> 
    </lightning-card> 
</template>


lwcLightningDataTableDemo.js
import { LightningElement,track } from 'lwc';
import getContacts from '@salesforce/apex/LWCDataTableExample.getContacts';

const columns = [ 
    { label: 'Id', fieldName: 'Id' }, 
    { label: 'First Name', fieldName: 'FirstName' }, 
    { label: 'Last Name', fieldName: 'LastName' }
];

export default class LwcLightningDataTableDemo extends LightningElement {
    @track contacts;
    @track error; 
    @track columns = columns;
   
    handleKeyChange( event ) { 
        const strLastName = event.target.value; 
        if ( strLastName ) { 
            getContacts( { strLastName } )   
            .then(result => { 
                this.contacts = result; 
                console.log('I am here',this.contacts);
               // console.log(JSON.stringify(result, null, '\t'));
   
            }) 
            .catch(error => { 
                this.error = error; 
            }); 
        } else 
        this.contacts = undefined; 
    }
}

lwcLightningDataTableDemo.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="lwcLightningDataTableDemo">
    <apiVersion>47.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
        <target>lightning__Tab</target>
    </targets>

</LightningComponentBundle>

NOTE:- Now from Winter 20 release we can Add Lightning Web Components as Custom Tabs for that we need to add lightning__Tab target to the component’s configuration file.

Now Your page will look like this


Lightning datatable inline edit


Let's see how we can do inline Edit
  • For inline editing we can use the uiRecordAPI. For that we need to import the "lightning/uiRecordApi"
  • We also need to add "onsave={handleSave}" and "draft-values={draftValues}"on lightning-datatable and on column we need to add enable "editable: true".
  • Then we need to add handler Save method.

Let's see how our code will look like:


lwcLightningDataTableDemo.html
<template>
    <lightning-card title = "Search Contacts" icon-name = "custom:custom63"> 
        <div class = "slds-m-around_medium"> 
            <lightning-input type = "search" onchange = {handleKeyChange} class = "slds-m-bottom_small" label = "Search" >
            </lightning-input> 
            <template if:true = {contacts}> 
                <div style="height: 300px;"> 
                    <lightning-datatable key-field="Id" 
                                            data={contacts} 
                                            columns={columns} 
                                            hide-checkbox-column="true" 
                                            show-row-number-column="true"
                                            onsave={handleSave}
                                            draft-values={draftValues}
                                            > 
                    </lightning-datatable> 
                </div>                  
            </template>
            <template if:true = {error}> 
                {error}> 
            </template> 
        </div> 
    </lightning-card> 
</template>


lwcLightningDataTableDemo.js
import { LightningElement,track } from 'lwc';
import getContacts from '@salesforce/apex/LWCDataTableExample.getContacts';

import { updateRecord } from 'lightning/uiRecordApi';
import { refreshApex } from '@salesforce/apex';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';


const columns = [ 
    { label: 'Id', fieldName: 'Id' }, 
    { label: 'First Name', fieldName: 'FirstName', editable: true  }, 
    { label: 'Last Name', fieldName: 'LastName', editable: true  }
];

export default class LwcLightningDataTableDemo extends LightningElement {
    @track contacts;
    @track error; 
    @track columns = columns;
    @track draftValues = [];
    handleKeyChange( event ) { 
        const strLastName = event.target.value; 
        if ( strLastName ) { 
            getContacts( { strLastName } )   
            .then(result => { 
                this.contacts = result; 
                // console.log('I am here',this.contacts);
                // console.log(JSON.stringify(result, null, '\t'));
            }) 
            .catch(error => { 
                this.error = error; 
            }); 
        } else 
        this.contacts = undefined; 
    }

    handleSave(event) {
        const recordInputs =  event.detail.draftValues.slice().map(draft => {
            const fields = Object.assign({}, draft);
            return { fields };
        });
   
        const promises = recordInputs.map(recordInput => updateRecord(recordInput));
       
        Promise.all(promises).then(contacts => {
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Success',
                    message: 'All Contacts updated',
                    variant: 'success'
                })
            );
             // Clear all draft values
             this.draftValues = [];
   
             // Display fresh data in the datatable
             return refreshApex(this.contact);
        }).catch(error => {
            // Handle error
        });
    }


}

Please check below post on Lightning Web Components:-

Check our YouTube Channel for more recording in Lightning Web Components.

Reference :-
1) https://developer.salesforce.com/docs/component-library/bundle/lightning-datatable/example
2) https://developer.salesforce.com/docs/component-library/documentation/lwc/data_table_inline_edit


Please share your feedback.

Sunday, 13 October 2019

Unlocked Packages | Modular Application Development Using Unlocked Packages | 2GP


Salesforce offers different types of packages (unmanaged, managed and Unlocked). Unlocked packages are especially suited for internal business apps and allowed you to do modular application development. Unlocked package is the right package type for most use cases, Unless you plan to distribute an app on AppExchange. You can use unlocked packages to organize your existing metadata, package an app, extend an app that you’ve purchased from AppExchange, or package new metadata.

Unlocked packages help you add, edit, and remove metadata in your org in a trackable way. You can install unlocked package to multiple orgs, and upgrade your Salesforce apps easier and faster. Metadata in unlocked packages can be modified in a production org ( You can do in case of emergency but not recommended).

Unlocked packages follow a source-driven development model. The source of truth of the metadata contained within the package is your version control system, not what’s in an org. This model brings with it all the advantages of modern source-driven development models.

We did one session on Unlocked Package in ApexHours With Mohith. Here is some highlight of that session.

What is Package ?

 

Packaging allows you to group various Salesforce Components (Apps, Tabs, Objects, Layouts, Workflows, Approval Process Flows, visualforce, apex, lightning components, profiles, permission sets and other metadata) for distribution or deployment. A package can also be defined as a container and allows for deployment of the components across various Salesforce organizations. Salesforce Set up UI and Salesforce CLI allows for creation of these. Package Creation yields a URL that allows it to install in various orgs


Difference Between Unmanaged package , Manage and Unlocked Package.

 

Unmanaged Package Managed Package Unlocked Package
Not upgradable  Upgradable and has namespace Upgradable and one can namespace them or choose not to
Metadata elements are not IP Protected Metadata elements are IP Protected Metadata elements are not locked and can be changed by system admins
Can we created in Salesforce UI Can be created in salesforce UI and distributed via appexchange Requires Salesforce CLI to generate them 
Unmanaged package containers automatically pull dependency Components are locked and one cannot modify them directly in production or sandbox Allows you to build your applications in a modular way

Allows for creation of extension packages Easier to manage when codebase is modularized

Modular Application Development Concepts

 

Break Your one monolithic app to multiple packages defining dependency between them. Unlock packages allow you to do them.


Building Unlocked packages using Salesforce CLI

 

Please check this recording for step by step process. Thank you so much Mohith for a great session in ApexHours. Here is agenda of session.
  1. Introduction To Salesforce Packaging
  2. Differentiate between unmanaged packages , managed packaged and unlocked packages
  3. Modular Application Development Concepts
  4. Building unlocked packages using salesforce cli
  5. Creating Dependency between packages
  6. Publishing and Installing Unlocked packages



Here is useful Salesforce DX command to create unlocked package. If you are new to SalesforceDX please check this recording.
  • One can create a package using below  
    sfdx force:package:create --name <name> --description <description> --packagetype Unlocked --path force-app --nonamespace --targetdevhubusername <Devhubalias>
  • Create a package version as below 
    sfdx force:package:version:create -p <packagename> -d force-app --wait 10 -v <Devhubalias>
  • Installation can also be done via the Salesforce CLI  
    sfdx force:package:install --wait 10 --publishwait 10 --package <packagename>@1.0.0-1 -r -u <alias>
  • By Default a BETA package is generated . We can promote a package using below 
    sfdx force:package:version:promote -p <packagename>@1.0.0-1 -v <DevHubalias>


References :-


Saturday, 31 August 2019

Trigger Framework Salesforce

In ApexHours we did one session on Apex Trigger Framework in Salesforce with ADAM OLSHANSKY. In that session we talk about what is a benefit of using a trigger framework, How many trigger framework are available, which one is lightweight apex trigger framework and Comparison of different approaches.

In that session we talk about all below Trigger Framework
1) Trigger Handler Pattern
2) Trigger Framework using a Virtual Class
3) Trigger Framework using an Interface
4) An architecture framework to handle triggers


Why Trigger Framework ?

 A framework may, however, greatly simplify your development efforts when your code base gets large. In a nutshell, your framework should have the following goals:-
  1. Generic code that can be extended for any object
  2. Ensures triggers are consistently handled and only required code is needed
  3. Allows for simple Triggers and Handlers
  4. Handles routing for you
  5. Enforces consistent trigger behavior
  6. Easily allows for trigger bypasses

Trigger Handler Pattern

Please check this post to learn about Handler pattern and code. Lets talk about what is the advantage of Trigger Handler Patter.
  1. Apex Class that handles trigger logic
  2. Allows code to be called from other code or tests
  3. Uses specific Trigger contexts and Trigger variables for routing
  4. Keep Triggers Simple
  5. Allow for greater flexibility
  6. Make code reusable
  7. Unit tests are much easier


Please check this recording for code walk-through. What is missing in Handler pattern ?
  1. Still duplicated code in every trigger
  2. How can we simplify things?
  3. How can we make our process repeatable?

Trigger Framework using a Virtual Class

 Please check this post to learn more about Virtual Class Trigger Framework.



Please check this recording for code walk-through. Accomplishments with this Trigger framework :-
  •  1 line trigger
  • Only need to add handler methods that we want to use
  • All routing is handled for us



Trigger Framework using an Interface

 Please check this post to learn about this framework.

 Please check this recording for code walk-through. Accomplishments with this Trigger framework :-

  • 1 line trigger
  • All routing is handled for us
  • All handlers are consistent and will have the same methods
  • Multiple ways to deactivate a trigger

An architecture framework to handle triggers

 Please check this post to learn about this framework.



Please check this recording for code walk-through. Accomplishments with this Trigger framework :-
  • 1 line trigger
  • All routing is handled for us
  • Establish all methods while letting us pick and choose which ones we want
  • Individual event handler methods

Please check our YouTube Recording to learn more about all Trigger Framework and Code.
https://www.youtube.com/watch?v=U5ZOA9EY3Kg&t=7s





Here is link for all frameworks:-

Thank