Salesforce Lightning Web Components

Hi All,

Today I will talk about Lightning Web Components, which will be generally available in February 2019 and will run in any Salesforce Org.

Lightning Web Components is a new programming model for building Lightning components. It holds web standards breakthroughs, can interoperate with the Aura programming model and delivers unique performance. To create and develop Lightning Web Components, you need to set up “Salesforce DX”.and “Visual Studio” code editor, which is the recommended Salesforce development environment. Here are the installation links:

Command Line Interface (CLI) :
Visual Code Studio :

-Now we need to Install below Visual Code Studio Extensions

  1. Salesforce Extension Pack
  2. Lightning Web Components
  3. Salesforce CLI Integration.
-Now we also need to run below commands in “Visual Studio” terminal. Here are the commands:
  1. sfdx plugins:install salesforcedx@pre-release
  2. sfdx plugins:install salesforcedx@latest
Now, we can run “sfdx plugins” command for check the installed plugins.

It should be show result like “salesforcedx 45.0.12 (pre-release)” it.

- Now, we are ready to create new lightning web component. First of all, we need to create new “Developer Edition Pre-Release Org”. Here is the creation link:

- Now, we need to create a new “Salesforce DX” project in our local machine. Here are the steps:

SFDX Project Creation Steps :

  1. In Visual Studio code, press Command + Shift + P on a Mac OR Ctrl + Shift + P on Windows.
  2. Type SFDX: Create Project.
  3. Enter MyLightningWebComponent as the project name, press Enter.
  4. Select a folder to store the project.
  5. Click Create Project.
- Now, we need to follow required steps to connect “Visual Studio” project with our Salesforce org.

  1. In Visual Studio code, press Command + Shift + P on a Mac OR Ctrl + Shift + P on Windows.
  2. SFDX: Authorize a Dev Hub: This step is used for login our pre-release Devhub Org.
  3. SFDX: Create a Default Scratch Org: We need to create new scratch org for pushing our changes from our local machine into scratch org.
  4. SFDX: Create Lightning Web Component: Now we need to create new lightning web component under “lwc” folder.
Now we will create a Lightning Web Component named ‘contactSearch’

Here’s the code:-


1:  <template>  
2:    <lightning-card icon-name="custom:custom57">  
3:      <div slot="title">  
4:        <lightning-layout vertical-align="center">  
5:          <lightning-layout-item>  
6:            Contact Search  
7:          </lightning-layout-item>  
8:          <lightning-layout-item padding="around-small">  
9:            <c-nav-to-new-record></c-nav-to-new-record>  
10:          </lightning-layout-item>  
11:        </lightning-layout>  
12:      </div>  
13:      <div class="slds-m-around_medium">  
14:        <lightning-input type="search" onchange={handleKeyChange} class="slds-m-bottom_small" 
15:           label="Search"></lightning-input>  
16:        <template if:true={contacts}>  
17:          <template for:each={contacts} for:item="contact">  
18:            <c-contact-tile key={contact.Id} contact={contact}></c-contact-tile>  
19:          </template>  
20:        </template>  
21:      </div>  
22:    </lightning-card>  
23:  </template>  


1:  lightning-input,  
2:  c-contact-tile {  
3:    position: relative;    
4:    border-radius: 4px;  
5:    display: block;  
6:    padding: 2px;  
7:  }  
8:  c-contact-tile {  
9:    margin: 1px 0;  
10:  }  
11:  lightning-input:before,  
12:  c-contact-tile:before {  
13:    color: #dddbda;  
14:    position: absolute;  
15:    top: -9px;  
16:    left: 4px;  
17:    background-color: #ffffff;  
18:    padding: 0 4px;  
19:  }  


1:  import { LightningElement, track } from 'lwc';  
2:  import findContacts from '@salesforce/apex/ContactController.findContacts';  
3:  /** The delay used when debouncing event handlers before invoking Apex. */  
4:  const DELAY = 350;  
5:  export default class ContactSearch extends LightningElement {  
6:    @track contacts;  
7:    @track error;  
8:    handleKeyChange(event) {  
9:      // Debouncing this method: Do not actually invoke the Apex call as long as this function is  
10:      // being called within a delay of DELAY. This is to avoid a very large number of Apex method calls.  
11:      window.clearTimeout(this.delayTimeout);  
12:      const searchKey =;  
13:      // eslint-disable-next-line @lwc/lwc/no-async-operation  
14:      this.delayTimeout = setTimeout(() => {  
15:        findContacts({ searchKey })  
16:          .then(result => {  
17:            this.contacts = result;  
18:            this.error = undefined;  
19:          })  
20:          .catch(error => {  
21:            this.error = error;  
22:            this.contacts = undefined;  
23:          });  
24:      }, DELAY);  
25:    }  
26:  }  


1:  <?xml version="1.0" encoding="UTF-8"?>  
2:  <LightningComponentBundle xmlns="">  
3:    <apiVersion>45.0</apiVersion>  
4:    <isExposed>true</isExposed>  
5:    <targets>  
6:      <target>lightning__AppPage</target>  
7:      <target>lightning__RecordPage</target>  
8:      <target>lightning__HomePage</target>  
9:    </targets>  
10:  </LightningComponentBundle>  

Now we will create a Lightning Web Component named ‘contactTile’

contactTile.html :
1:  <template>  
2:    <lightning-layout vertical-align="center">  
3:      <lightning-layout-item>  
4:        <img src={contact.Picture__c} alt="Profile photo">  
5:      </lightning-layout-item>  
6:      <lightning-layout-item padding="around-small">  
7:        <a onclick={navigateToView}>{contact.Name}</a></p>  
8:        <p>{contact.Title}</p>  
9:        <p>  
10:          <lightning-formatted-phone value={contact.Phone}></lightning-formatted-phone>  
11:        </p>  
12:      </lightning-layout-item>  
13:    </lightning-layout>  
14:  </template>  


1:  img {  
2:    width: 60px;  
3:    height: 60px;  
4:    border-radius: 50%;  
5:  }  


1:  import { LightningElement, api } from 'lwc';  
2:  import { NavigationMixin } from 'lightning/navigation';  
3:  //import getSingleContact from '@salesforce/apex/ContactController.getSingleContact';  
4:  export default class ContactTile extends NavigationMixin(LightningElement) {  
5:    @api contact;  
6:   // @wire(getSingleContact) contact;   
7:    navigateToView() {     
8:     this[NavigationMixin.Navigate]({  
9:      type: "standard__recordPage",  
10:        attributes: {  
11:          objectApiName: "Contact",  
12:          actionName: "view",  
13:          recordId:,  
14:        },  
15:      });  
16:   }    
17:  }  


1:  <?xml version="1.0" encoding="UTF-8"?>  
2:  <LightningComponentBundle xmlns="">  
3:    <apiVersion>45.0</apiVersion>  
4:    <isExposed>false</isExposed>  
5:    <targets>  
6:      <target>lightning__AppPage</target>  
7:      <target>lightning__RecordPage</target>  
8:      <target>lightning__HomePage</target>  
9:    </targets>  
10:  </LightningComponentBundle>  

Now we will create a Lightning Web Component named ‘navToNewRecord’

1:  <template>  
2:      <lightning-button label="New Contact" variant="brand" class="slds-m-around_medium" 
3:      onclick={navigateToNewContact} ></lightning-button>  
4:  </template>  


1:  import { LightningElement } from 'lwc';  
2:  import { NavigationMixin } from 'lightning/navigation';  
3:  export default class NavToNewRecord extends NavigationMixin(LightningElement) {  
4:    navigateToNewContact() {  
5:      this[NavigationMixin.Navigate]({  
6:        type: 'standard__objectPage',  
7:        attributes: {  
8:          objectApiName: 'Contact',  
9:          actionName: 'new',  
10:        },  
11:      });  
12:    }  
13:  }  


1:  <?xml version="1.0" encoding="UTF-8"?>  
2:  <LightningComponentBundle xmlns="" fqn="navToNewRecord">  
3:    <apiVersion>45.0</apiVersion>  
4:    <isExposed>true</isExposed>  
5:    <targets>  
6:      <target>lightning__AppPage</target>  
7:      <target>lightning__RecordPage</target>  
8:      <target>lightning__HomePage</target>  
9:    </targets>  
10:  </LightningComponentBundle>  

Here’s the GitHub link for further files which are required before pushing to scratch org for this tutorial
Files which are required:-
Picture__c.field-meta.xml file for creating a custom field
lwc.permissionset-meta.xml file for assigning permission
‘data’ named the folder for loading data

Push to a Scratch Org

Type :SFDX: Push Source to Default Scratch Org by using Ctrl + Shift + P  OrType in terminal
sfdx force:source:push [-u<Username>]

Assign the lwc permission set to the default user:

sfdx force:user:permset:assign -n lwc

Load sample data:

sfdx force:data:tree:import --plan ./data/data-plan.json

Add Component to App in Lightning Experience

  1. Type SFDX: Open Default Org.
  2. Click the app launcher icon App Launcher to open the App Launcher.
  3. Select the Sales app.
  4. Click the gear icon Setup Gear to reveal the Setup menu, then select Edit Page.
  5. Drag the contactSearch Lightning web component from the list of custom components to the top of the Page Canvas.

Deploy it to your Pre-release org:
Log in to your Pre-Release org and create an alias for it.
To deploy we have to also push further files which I’ve mentioned above
Type the following commands in VS Code terminal:
sfdx force:auth:web:login -a MyOrg
Confirm that this org is available:
sfdx force:org:list
Deploy your code to Pre-Release org
sfdx force:source:deploy -p force-app  -u MyOrg
Assign the lwc permission set to the default user:
sfdx force:user:permset:assign -n lwc -u MyOrg
Load sample data:
sfdx force:data:tree:import --plan ./data/data-plan.json -u MyOrg
Run your org  and interact with the app:
sfdx force:org:open -u MyOrg

How I prepared for Salesforce certified app builder exam

How I prepared for Salesforce certified app builder exam

Hi All,

On 31st August 2018 I cleared Salesforce Platform App Builder Certification exam. And as soon I posted on social media I started to get question regarding the preparation that how I prepared, So finally I am writing my all the steps I took for this certification. Before starting I would like say a big thanks to my collegues and mentors(Aslam Bari , Ranu Bari , Naveen Soni) for motivating and guiding me for this exam.

When I decided for App builder exam, I got a very first question asked from my friends that, you are a developer then why you are going for this certification. You must go for Platform Developer2.So here is answer for all.
As we all know salesforce provides so many out of the box No Code  tools, using them we can complete so many business requirements.We do not need to write a single line of code. So being a developer I should be having knowledge about these tools,becasuse it can save my efforts and increase my work efficiancy, and I was having that much knowledge. Then Why should not I appear in exam and get my skills certified from the salesforce. It was not wasting money/time. It was an investment so I did it.

So let’s start talking about exam. I took around 25 to 30 Hours in preparation of exam.
First of all I took a deep review of official exam guide, and analysis about which section cover higher ratio of question in exam and how much I am confident in that. So if you see the exam guide you will see that these are the topic which covers more then 70% of exam. And to clear exam you need only 63%.

Data Modeling And Management(20%)
Business Logic And Process Automation(27%)
User Interface (14%)

You need to focus more on these topics. Most the question for these topics will be scenario based question. While answering the question remind the consideration for every option. It will help you to eliminate the answer so you can select the right answers.

There are some another topic also
Salesforce fundamentals(8%) : In this section very basic questions would be there, Such as a scenario will be given and you need to identify that should you search for a solution on appexchange.

Social (3%): 1 or 2 question would be in exam.

Reporting(5%): Read about the report types and standard reports available. Which reports are available for chart.

Mobile(5%): Read about the customize saleforce mobile app. Such as navigation, buttons on detail page etc.

App Devlopment(8%): Difference between managed and unmanaged package, when to use change set and when to use other migration tools.

Here are some other steps which I took.

  • Also read about the consideration about process automation tools, lookup/master detail fields, formula fields , roll upsummary. So you can understand when not to use them.

  • I also used an mobile app cram which was suggested by one of my Salesforce Ohana friend Bharat Kumar. On this app you will find flash cards , which are helpful for revising the topics. I used to do practice on this app before going to bed. And it was really helpful. I would like to say a big thank to Bharat for letting me know about this app.

Let me know your suggestions in comment section.

lightning:empApi Salesforce Winter19


Hi All,
Today I will talk about brand new lightning component lightning:empApi , Which was delivered in winter 19 salesforce realease.

When to use empApi:  To see live data in on lightning component.

We had serval options to do this such as polling which is an old technique in this we call server (Apex class) again and again. Or we use streaming api, and cometD JS (external javascript) which requires lots of efforts.

Drawbacks of polling (Calling apex server) : In this we need to travel to server after every particular interval. In this sometimes our server trip is useless , if we do not have any latest data there. 

But now we have an native lightning component (lightning:empApi) , which is very helpful and reducse developer's effort.

lightning:empApi can only be used in desktop browser only and require API version 44.0 and higher. lightning:empApi can be used with platform events, PushTopic events, generic events and Change Data Capture events.

Let's see an example of lightning:empApi with platform events. My colleague Aslam bari already have written an outstanding blog (quick demo salesforce platform events) on Platform event.

In our example we will display all case which has status = open. We would not reload our component and will see live/latest data.


So firts of all we will create a new platform event.
I have created platform event (UpdateRecord__e).

Then we need to publish it whenever a new case is inserted with status = 'open'. As well as you can also publish platform event when status is changed from open to any other or vice versa. And same you can do for delete also.


trigger CaseTrigger on Case (after insert) { List<Case> listOfOpenCase = new List<Case>(); for(Case objCase :{ if(objCase.Status == 'Open'){ listOfOpenCase.add(objCase); } } if(listOfOpenCase.size() > 0){ EventBus.publish(new UpdateRecord__e(message__c = listOfOpenCase[0].id)); } }


<aura:component controller="empApiExampleController" implements="force:appHostable"> <aura:handler name="init" value="{!this}" action="{!c.doInit}"></aura:handler> <aura:attribute name="listOfCases" type="List"/> <aura:attribute name="subscription" type="Map" /> <aura:attribute name="showSpinner" type="Boolean" default="false"/> <lightning:empApi aura:id="empApi"/> <aura:if isTrue="{!v.showSpinner}"> <lightning:spinner size="small"/> </aura:if> <lightning:card title="empApi Example" footer=""> <div> <table class="slds-table slds-table_cell-buffer slds-table_bordered"> <thead> <tr class="slds-line-height_reset"> <th class="slds-text-title_caps" scope="col"> <div class="slds-truncate" title="Opportunity Name">Case Subject</div> </th> <th class="slds-text-title_caps" scope="col"> <div class="slds-truncate" title="Account Name">Priority</div> </th> <th class="slds-text-title_caps" scope="col"> <div class="slds-truncate" title="Close Date">Reason</div> </th> </tr> </thead> <tbody> <aura:iteration items="{!v.listOfCases}" var="objCase"> <tr class="slds-hint-parent"> <td data-label="Case Subject"> <div class="slds-truncate" title="Cloudhub">{!objCase.Subject}</div> </td> <td data-label="Case Priority"> <div class="slds-truncate" title="Cloudhub">{!objCase.Priority}</div> </td> <td data-label="Case Reason"> <div class="slds-truncate" title="Cloudhub">{!objCase.Reason}</div> </td> </tr> </aura:iteration> </tbody> </table> </div> </lightning:card> </aura:component>


({ doInit : function(component, event, helper) { helper.getData(component); // Get the empApi component. var empApi = component.find("empApi"); // Error handler function that prints the error to the console. var errorHandler = function (message) { console.error("Received error ", JSON.stringify(message)); }; // Register error listener and pass in the error handler function. empApi.onError(errorHandler); var channel = '/event/UpdateRecord__e'; // platform event name var replayId = -1; var callback = function (message) { console.log("Event Received : " + JSON.stringify(message)); helper.getData(component); }; // Subscribe to the channel and save the returned subscription object. empApi.subscribe(channel,replayId, callback).then(function(newSubscription) { component.set("v.subscription", newSubscription); // can be used if you want to unsubscribe event }); } })


({ getData : function(component) { component.set("v.showSpinner",true); var action = component.get('c.getListOfCases'); action.setCallback(this,function(response){ if(response.getState() === "SUCCESS"){ component.set("v.listOfCases",response.getReturnValue()); component.set("v.showSpinner",false); } }); $A.enqueueAction(action); } })

empApiExampleController (Apex)

public class empApiExampleController { @AuraEnabled public static List<Case> getListOfCases(){ return [SELECT Id,Subject,Priority,Reason FROM Case WHERE Status = 'Open']; } }


Lightning Data Services

Lightning Data Services

What is LDS :
                        LDS is Lightning Component that display the data on Page in Salesforce  Lightning. Using LDS we don’t need any apex  controller to perform CRUD operation. using LDS we can increase the performance. It also provide the way to cache the data to work offline in case user is not connected to network. Once the connection is restored data will sync.
LDS also handle Field Level Security and sharing rules security. Record loaded in Lightning Data Services are stored in cache and shared between all components.Using LDS all component performance is increase because data is loaded once and used by many component, no need to make separate request from different-different components . when any of the component  updates  a record then other component will  automatically updated with new value.

force:recordData :
                                    This tag is must be used to load the data in component  using LDS.
Attributes of force:recordData : 
recordId : Id of current page record that will be load
      mode : (Edit,View) its depend on what operation we are performing. If we want to update,create then Mode=’Edit’ else Mode=’View’
layoutType : specify the layout type to display record and its determine what field are included in component. 
          fields : specifies which fields in the record to query.

Target Attribute :
1.      targetRecord  : populate with loaded record.
2.      targetField      : view of loaded record.
3.     targetError      :  populate with error.    

Methods :
1.      saveRecord() : insert of update the current record in force:recordData.
2.      deleteRecord() : delete the current record in force:recordData.
3.      getNewRecord() :  load the new record instance to insert the record of that object from force:recordData.
4.      reloadRecord() : reload the current record with new data.

Keep In Mind When Using It :
i.                LDS is simple but it’s not complete replacement of apex controller.
ii.              LDS is not supported in lightning out and visualforce page. Its only for lightning.
iii.            LDS perform CRUD only on single record. It’s not supported for bulk data.
iv.             In Summer 17, release LDS used force:recordPreview component.But now it’s completely replaced by force:recordData. Difference between force:recordPreview  and force:recordData  is force:recordData  returns record in new shape using UI API and targetfield is added in parameter.
v.               To update from force:recordPreview  to force:recordData is to change reference from targetRecord to targetField.
vi.              If you want to query multiple operations in one transaction then use apex controller @AuraEnabled.

Example :
            Here we are creating a component that is added on Account detail page. It will create a new contact for current account record.

1. Create a new Record :

    Lightning Component :
    <aura:component implements="flexipage:availableForRecordHome, force:hasRecordId">
<aura:attribute name="newContact" type="Object"/>
<aura:attribute name="createContact" type="Object"/>
<aura:attribute name="newContactError" type="String"/>
<force:recordData aura:id="contactRecordCreator"
    targetFields ="{!v.createContact}"
<aura:handler name="init" value="{!this}" action="{!c.doInit}"/>
            <div class="Create Contact">
                        <lightning:card iconName="action:new_contact" title="Create Contact">
                                                <div class="slds-p-horizontal--small">
<lightning:input aura:id="contactField" label="First Name" value="{!v.createContact.FirstName}"/>
<lightning:input aura:id="contactField" label="Last Name" value="{!v.createContact.LastName}"/>
<lightning:button label="Save Contact" variant="brand" onclick="{!c.handleSaveContact}"/>
    <aura:if isTrue="{!not(empty(v.newContactError))}">
        <div class="recordError">

   Lightning Controller :
    doInit: function(component, event, helper) {
            "Contact", // sObject type (entityAPIName)
            null,      // recordTypeId
            false,     // skip cache?
            $A.getCallback(function() {
                var rec = component.get("v.newContact");
                var error = component.get("v.newContactError");
                if(error || (rec === null)) {
                    console.log("Error initializing record template: " + error);
                else {
                    console.log("Record template initialized: " + rec.sobjectType);
    SaveContact: function(component, event, helper) {
        component.set("v.createContact.AccountId", component.get("v.recordId"));
        component.find("contactRecordCreator").saveRecord(function(saveResult) {
            if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                var resultsToast = $A.get("e.force:showToast");
                    "title": "Saved",
                    "message": "New Contact ."
            } else if (saveResult.state === "INCOMPLETE") {
                console.log("User is offline, device doesn't support drafts.");
            } else if (saveResult.state === "ERROR") {
            } else {
                console.log('Unknown problem, state: ' + saveResult.state);
Result :

2. Delete A record :
            Here we added Delete Component on Account Detail Page. It will Delete Current Account when we click on Delete Button in below component.

Lightning Component :
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId">
    <aura:attribute name="recordError" type="String" access="private"/>
    <force:recordData aura:id="dataRecord"
     <div class="Delete Record">
            <lightning:card iconName="delete" title="Delete Record">
                                    <div class="slds-p-horizontal--small">
<lightning:button label="Delete Record" variant="destructive" onclick="{!c.handleDeleteRecord}"/>
    <aura:if isTrue="{!not(empty(v.recordError))}">
        <div class="recordError"> {!v.recordError}</div>

Lightning Controller :
handleDeleteRecord: function(component, event, helper) {
             component.find("dataRecord").deleteRecord($A.getCallback(function(deleteResult) {
            if (deleteResult.state === "SUCCESS" || deleteResult.state === "DRAFT") {
                console.log("Record is deleted.");
            } else if (deleteResult.state === "INCOMPLETE") {
                console.log("User is offline, device doesn't support drafts.");
            } else if (deleteResult.state === "ERROR") {
                console.log('Problem deleting record, error: ');
            } else {
                console.log('Unknown problem, state: ');
 handleRecordUpdated: function(component, event, helper) {
        var eventParams = event.getParams();
        if(eventParams.changeType === "CHANGED") {
        } else if(eventParams.changeType === "LOADED") {
        } else if(eventParams.changeType === "REMOVED") {
            var resultsToast = $A.get("e.force:showToast");
                "title": "Deleted",
                "message": "The record was deleted."

        } else if(eventParams.changeType === "ERROR") { }

Result :

3. Update a Record :
            Here We create a component that will update the account detail on Account Detail page on click of save Button in component.

Lightning Component :
<aura:component implements="flexipage:availableForRecordHome,force:hasRecordId">
    <aura:attribute name="record" type="Object"/>
    <aura:attribute name="accRecord" type="Object"/>
    <aura:attribute name="recordError" type="String"/>
    <force:recordData aura:id="recordHandler"
    <div class="Record Details">
        <lightning:card iconName="action:edit" title="Edit Account">
            <div class="slds-p-horizontal--small">
               <lightning:input label="Account Name" value="{!v.accRecord.Name}"/>
               <lightning:button label="Save Account" variant="brand" onclick="{!c.SaveRecord}" />
    <aura:if isTrue="{!not(empty(v.recordError))}">
        <div class="recordError">

Lightning Controller :
    SaveRecord: function(component, event, helper) {
        component.find("recordHandler").saveRecord($A.getCallback(function(saveResult) {
            if (saveResult.state === "SUCCESS" || saveResult.state === "DRAFT") {
                console.log("User drafts.");
            } else if (saveResult.state === "INCOMPLETE") {
                console.log("User is offline, device doesn't support drafts.");
            } else if (saveResult.state === "ERROR") {
                console.log('Problem saving record, error: ' + JSON.stringify(saveResult.error));
            } else {
                console.log('Unknown problem, state: ' + saveResult.state + ', error: ' + JSON.stringify(saveResult.error));

Result :