Featured

Salesforce – Lightning web components with Quick actions

Salesforce recently announced lightning web components to be GA feature. In a major effort to standardize the UI web developments, lightning web components (LWC)are a major foot forward. Interestingly, Salesforce is not moving away from the Aura framework, and lightning web components will coexist and interact with each other. To get a better understanding of this new programming model, we will try to create a quick action using LWC model

Entire code is available at this Github Location

Use Case – Create a quick action on the contact object, which will display sample contact fields values (name, email, phone, title).

Design – To demonstrate the working of this functionality, we will create a quick action. Quick action will call the lightning component. Lightning component will pass the record id of contact to the lightning web component. Finally Lightning web component will make standard call to fetch contact details.

  • Quick Action – To be created on Contact Object
  • Lightning Component (Aura) – Quick action will execute the this component, which in turn will call the lightning web component
  • Lightning Web Component

Quick Action

Quick Action configuration is standard and calls the lightning component.

Lightning Component

<aura:component implements="force:lightningQuickActionWithoutHeader,force:hasRecordId" >
    <c:contactDetailsLWC recordId="{!v.recordId}"/>
</aura:component>

As you can see in the second line we are passing the record id to the Lightning web component

Lightning Web Component

// ContactDetailsLWC.html
<template>
    <lightning-card
        title="Contact Information"
        icon-name="standard:contact"
    >
    <template if:true={contact.data}>
            <lightning-layout vertical-align="center">
                    <lightning-layout-item padding="around-small">
                            <p>Name : {name}</p>
                            <p>Account :{accountname}</p>
                            <p>Phone :{phone}</p>
                            <p>Email :{email}</p>
                        </lightning-layout-item>        
            </lightning-layout>
    </template>
</lightning-card>
</template>
//contactDetailsLWC.js
import { LightningElement,api, wire  } from 'lwc';
import { getRecord, getFieldValue } from 'lightning/uiRecordApi';
import NAME_FIELD from '@salesforce/schema/Contact.Name';
import TITLE_FIELD from '@salesforce/schema/Contact.Title';
import PHONE_FIELD from '@salesforce/schema/Contact.Phone';
import EMAIL_FIELD from '@salesforce/schema/Contact.Email';
import ACCOUNT_NAME_FIELD from '@salesforce/schema/Contact.Account.Name';

const fields = [NAME_FIELD, TITLE_FIELD, PHONE_FIELD, EMAIL_FIELD,ACCOUNT_NAME_FIELD];

export default class ContactDetailsLWC extends LightningElement {
    @api recordId;
    @api objectApiName = 'Contact';
    accountName = NAME_FIELD;
    @wire(getRecord, { recordId: '$recordId', fields })
    contact;

    get name() {
        return getFieldValue(this.contact.data, NAME_FIELD);
    }
    get accountname() {
        return getFieldValue(this.contact.data, ACCOUNT_NAME_FIELD);
    }
    get title() {
        return getFieldValue(this.contact.data, TITLE_FIELD);
    }
    get phone() {
        return getFieldValue(this.contact.data, PHONE_FIELD);
    }
    get email() {
        return getFieldValue(this.contact.data, EMAIL_FIELD);
    }
}

In the javascript file, recordId variable is declared as @api (public variable). This variable will receive record id from aura component and will use the @wire to fetch contact details. Finally, getter methods will retrieve field values from the contact variable.

Your job is your career, not just a job

Yes, we all have heard that phrase a number of times, so much that we sometimes do not even consider how powerful this statement is. Let’s try to understand this from a different perspective and see if we can get to the roots.

Let me begin by asking some basic questions, are you hooked to any sport? Do you follow any professional athlete and wonder how great their career is? Do you follow any celebrities or famous personalities? I know the answer is yes, if your answer is on the other side, don’t even bother reading further.

Let’s take an example of a professional athlete, we hear all the time how focussed they are for the coming season, how they are following a special diet, workout plan, improving techniques or skill, training with coaches and the list can go on, but you get the point.

So to pursue their “Career”, they make sure no stone is unturned, and the fact of the matter is that they are focused, and know that everything counts, I repeat they know everything counts

To draw a parallel, most of us in 9-5 jobs, or whatever the work timings are, why do we consider job as just a ‘Job’ not a ‘Career’. Let’s see what is stopping us from calling job as ‘Career’

Name/Fame/Remuneration – You may argue here that there are millions of dollars on the line for them, and clearly regular job does not pay that well. Well, the argument can be made that was there millions of dollars on the line when the started their career? We all know deep inside that it was the hunger to succeed that got them the to focus, not millions or the fame, otherwise they would have never made it to the top.

Lack of passion – This is a very valid reason for not calling your work as a career, something that doesn’t drive you, wakes you up, cheers you when you accomplish. I rest my case.

If you do not agree with the above statement, you have every right to call your work as ‘Career’. And when you call it that, you are obligated to the following.

Train for your work like an athlete, work hard, watch what you eat, choose the wise company, train your mind, get a workout plan, get a mentor, acquire more skill, be a rockstar at your work because you know why, EVERYTHING COUNTS

Promises with lightning web components, Explained!!!

The standard definition for promise says that Promise is the object which can produce some value in the future. These objects are used in asynchronus calls, where we can not predict time to complete the transaction. Promise helps to perform actions based on the results of the asynchronous calls.

Promises Terminology

  • Fulfilled – Indicates that the action has completed without errors
  • Rejected – Indicates that the action has failed with errors
  • Pending – Indicates that the action still is in flight

Let see the syntax below

Promise Declaration – The function declared below returns a promise. For the understanding, lets put a sample timeout in the function body.

Function makeAsyncCall(msg){ 
return new Promise((resolve, reject) => {
      setTimeout(
        () => {
          console.log(msg);
          resolve();
        }, 
        1000);
    }) 
}

Promise Execution – While calling this function in the Javascript, we can call it using the below syntax. Then segment will execute when the promise is complete, and similarly catch function will execute in the action failure.

            makeAsyncCall('msg')
            .then(result => {
                console.log('This promise is resolved')
            })
            .catch(error => {
                console.log('This promise has failed')
            });

This is so simple, but yet so powerful. Let’s see some benefits of using Promises

Chaining of Events

            makeAsyncCall('msg')
            .then(result => {
                console.log('This promise is resolved')
                // Call a new promise in here
            })
            .catch(error => {
                console.log('This promise has failed')
            });

Then block refers to the successful action on the event, we can use the same block to call another promise function inside then block. Hence you can keep chain multiple actions using promises

Error Handling

As seen in the above example, we can associate catch block with a promise. Every time an action on a promise fails, execution goes the the catch block, and statements in the catch block are implemented. We usually use some error handling or showing error toast messages in the catch block

LWC – Radio with Checkboxes

What are we doing here ?

If you are new to Lightning Web Components (so is Salesforce by the way), and have come across a use case to implement radio options, where option set is rendered by dynamic values, there are very little options. Currently radioinput is supported by aura component but not by LWC. And thus we did a little trick here. Read the SF documentation

In the post below we will see how we can implement radio button functionality using the checkboxes.

What is the trick?

We all know the check boxes are multi select by default. However to make it behave as radio buttons, we created small javascript code to unselect all options and select the current option, thus at any moment there will be only one selection in the list

Enough talk, lets dive into the code. Also if you would like to fork/clone/whatever, here is the link to the github code

Radio.html

<template>
    <lightning-card title="Contacts">
        <div class="slds-m-around_medium">
            <template for:each={contacts.data} for:item="contact">
                <lightning-input 
                key={contact.Id} 
                label={contact.Name} 
                type="checkbox" 
                data-value={contact.Id} 
                onchange={handleChangeEvent}>
            </lightning-input>
            </template>
        </div>
    </lightning-card>
</template>

Simple HTML code, all it does is that I loops through the contacts array, iterates over in the lightinig input. Please note we have associated handleChangeEvent to our lightning input (or checkboxes)

Radio.js

import { LightningElement,wire } from 'lwc';
import getContactList from '@salesforce/apex/ContactController.getContactList';

export default class RadioWithCheckbox extends LightningElement {
    @wire(getContactList)
    contacts;
    handleChangeEvent(event){
        Array.from(this.template.querySelectorAll('lightning-input'))
        .forEach(element => {
            element.checked=false;
        });
        const checkbox = this.template.querySelector('lightning-input[data-value="'+event.target.dataset.value+'"]');
        checkbox.checked=true;
    }
}

Few things to note here

  • Contact list is populated using the apex controller
  • QueryselectorAll fetches all the lightning input and deselects them
  • Queryselector fetches the current lightning input based on the event value (we used contact id as the key to lightning-input), and mark the current lightning input as checked

I have full faith in your intelligence that you will not need meta file

Happy Coding Everyone, please drop in your suggestions below, I would love to discuss and ARGUE