CRON Expression in Salesforce

  

Using CRON Expression in Salesforce

Hello to all the salesforce developers, here in this blog I am covering a very crucial topic that we all use in our coding skills - CRON expression. As we all know that Salesforce provides us with a very great feature of Scheduling an apex class. In a standard way through customization part, we can schedule an apex class with the frequency of weekly days or monthly dates with a preferred start time. But through CRON expression we can schedule an apex with our customized date time or occurrence through code. That’s an interesting feature that salesforce allows developers to customize according to customize according to their own need and scenario.

cron1

What is CRON?

CRON is a software utility that is a time-based job scheduler in Unix-like computer operating systems. Developers who want to set up and maintain software environments, use this CRON to schedule jobs (commands or shell scripts) to run periodically at fixed times, dates, or intervals.

dont miss out iconDon't forget to check out: Wrapper Class in Apex Salesforce | The Developer Guide

What is CRON expression?

A CRON expression is basically a string of five or six fields separated by white spaces that represents a set of times, normally as a schedule to execute some routine.

Use in Salesforce

Use schedule with an Apex class that implements the Schedulable interface to schedule the class to run at the time specified by a Cron expression.

System.Schedule(JobName, CronExpression, SchedulableClass);

The System.Schedule method takes three arguments: a name for the job, an expression used to represent the time and date the job is scheduled to run, and the name of the class.

Sample Code

TestSchedulableClass testobj = new TestSchedulableClass();
String cronexpression = ‘0 0 0 ? * * *’;
System.schedule(‘Testing’, cronexpression, testobj);

The Above Code Executes TestSchedulableClass At 12:00 AM Every Day.

CRON expression has the following syntax:

0 0 5 ? * 1,2,3,4,5,6,7
{1} {2} {3} {4} {5} {6}

{1} Seconds - so 0 here i.e. start of the minute.

{2} Minutes - 0 again so start of the hour.

{3} Hours -  5 so 5 am. Uses 24 hour notation so 21 = 9pm

{4} Day_of_month - ? means no specific value, only available for day of the month and day of the week.

{5} Month - * indicates all values, i.e. every month. (if we only want to run on 1st Jan say, this would be 1)

{6} Day_of_week - 1,2,3,4,5,6,7 here specifies days 1,2,3,4,5,6,7 in the week. We could also write this string as MON-FRI or preferably as * to indicate all values.

So this job reads to run at "0 seconds past 0 minutes of the 5th hour on no specified day of the month for every month of the year for every day of the week".

The following are the values for the expression:

cron2

The special characters are defined as follows:

cron3

NOTE: Use the L and W together to specify the last weekday of the month.

Cron Expression Examples

cron4

dont miss out iconLearn more about: Queueable Apex in Salesforce - Concept to Implementations

Example to schedule a class for every 5 min

System.schedule(Schedule Job Name 1',  '0 00 * * * ?', new testScheduleFiveMinutes());

System.schedule(Schedule Job Name 2',  '0 05 * * * ?', new testScheduleFiveMinutes());

System.schedule(Schedule Job Name 3',  '0 10 * * * ?', new testScheduleFiveMinutes());

System.schedule(Schedule Job Name 4',  '0 15 * * * ?', new testScheduleFiveMinutes());

System.schedule(Schedule Job Name 5',  '0 20 * * * ?', new testScheduleFiveMinutes());

System.schedule(Schedule Job Name 6',  '0 25 * * * ?', new testScheduleFiveMinutes());

System.schedule(Schedule Job Name 7',  '0 30 * * * ?', new testScheduleFiveMinutes());

System.schedule(Schedule Job Name 8',  '0 35 * * * ?', new testScheduleFiveMinutes());

System.schedule(Schedule Job Name 9',  '0 40 * * * ?', new testScheduleFiveMinutes());

System.schedule(Schedule Job Name 10', '0 45 * * * ?', new testScheduleFiveMinutes());

System.schedule(Schedule Job Name 11', '0 50 * * * ?', new testScheduleFiveMinutes());

System.schedule(Schedule Job Name 12', '0 55 * * * ?', new testScheduleFiveMinutes());

Hope you all get a quick idea of CRON expression. Have fun with CRON and built your schedulers as per your requirements.

Client Side Pagination and Search in Lightning Web Component

  Client side pagination and search in lightning web component

In this example, you have create one apex class and one lwc. In the apex handler i am using account object records but you can use any objects as per your need.

AccountHandler.apxc

 public class AccountHandler {
@AuraEnabled(cacheable=true)
public static List<Account> getAccounts(String searchKey, String sortBy, String sortDirection) {
String query = 'SELECT Id, Name,Phone,Type FROM Account';
if (String.isNotEmpty(searchKey)) {
String key = '%' + searchKey + '%';
query += ' WHERE Name LIKE :key';
}
if (String.isNotEmpty(sortBy) && String.isNotEmpty(sortDirection)){
query += ' ORDER BY ' + sortBy + ' ' + sortDirection;
}
return Database.query(query);
}
}
ClientSidePagination.html
 <template>
<template if:true={loader}>
<lightning-spinner alternative-text="Loading..." size="small"></lightning-spinner>
</template>
<lightning-layout>
<lightning-layout-item padding="around-small" size="4">
<lightning-combobox style="width:80px;" name="StageName" label="Show Entries" value={pageSize} options={options}
onchange={handleChange}></lightning-combobox>
</lightning-layout-item>
<lightning-layout-item style="padding-top: 34px;" size="4">
<center>
<lightning-button icon-name="utility:desktop" label="Show Selected Account" variant="brand" onclick={showSelectedAccounts}></lightning-button>
</center>
</lightning-layout-item>
<lightning-layout-item padding="around-small" size="4">
<lightning-input type="search" onchange={handleKeyChange} class="slds-m-bottom_small" label="Search"

value={searchKey} placeholder="Type Account Name..">
</lightning-input>
</lightning-layout-item>
</lightning-layout>
<lightning-card title="Client Side Pagination With Search" icon-name="standard:account">
<lightning-datatable data-id="table" key-field="Id" data={data} columns={columns} sorted-by={sortedBy}
sorted-direction={sortedDirection} onrowselection={onRowSelection} selected-rows={allSelectedRows}
onsort={sortColumns}>
</lightning-datatable>
<div class="slds-m-around_medium">
<center>
<lightning-button label="Previous" variant="brand" icon-name="utility:chevronleft" onclick={previousHandler}>
</lightning-button>
&nbsp; Page {page} of {totalPage} &nbsp;
<lightning-button label="Next" variant="brand" icon-name="utility:chevronright" icon-position="right"
onclick={nextHandler}>
</lightning-button>
</center>
</div>
</lightning-card>

<template if:true={isModalOpen}>
<!-- Modal/Popup Box LWC starts here -->
<section role="dialog" tabindex="-1" aria-labelledby="modal-heading-01" aria-modal="true" aria-describedby="modal-content-id-1" class="slds-modal slds-fade-in-open">
<div class="slds-modal__container">
<!-- Modal/Popup Box LWC header here -->
<header class="slds-modal__header">
<button class="slds-button slds-button_icon slds-modal__close slds-button_icon-inverse" title="Close" onclick={closeModal}>
<lightning-icon icon-name="utility:close" alternative-text="close" variant="inverse" size="small" ></lightning-icon>
<span class="slds-assistive-text">Close</span>
</button>
<h2 id="modal-heading-01" class="slds-text-heading_medium slds-hyphenate">Selected Account List</h2>
</header>
<!-- Modal/Popup Box LWC body starts here -->
<div class="slds-modal__content slds-p-around_medium" id="modal-content-id-1">
<p>
<lightning-datatable data-id="SelectedAcctable" key-field="Id" data={allSelectedRows} columns={columns}
hide-checkbox-column="false" show-row-number-column="true">
</lightning-datatable>
</p>
</div>
<!-- Modal/Popup Box LWC footer starts here -->
<footer class="slds-modal__footer">
<button class="slds-button slds-button_destructive" onclick={closeModal} title="Close">Close</button>
</footer>
</div>
</section>
<div class="slds-backdrop slds-backdrop_open"></div>
</template>
</template>
ClientSidePagination.js
 import { LightningElement, wire, api, track } from 'lwc';
import { refreshApex } from '@salesforce/apex';
import getAccounts from '@salesforce/apex/AccountHandler.getAccounts';
const columns = [
{ label: 'Name', fieldName: 'Name', type: 'text', sortable: true },
{ label: 'Phone', fieldName: 'Phone', sortable: true },

{ label: 'Type', fieldName: 'Type', sortable: true }
];
export default class ClientSidePagination extends LightningElement {
@track loader = false;
@track isModalOpen = false;
@track value;
@track error;
@track data;
@api sortedDirection = 'asc';
@api sortedBy = 'Name';
@api searchKey = '';
result;
@track allSelectedRows = [];
@track page = 1;
@track items = [];
@track data = [];
@track columns;
@track startingRecord = 1;
@track endingRecord = 0;
@track pageSize = '5';
@track totalRecountCount = 0;
@track totalPage = 0;
isPageChanged = false;
initialLoad = true;
mapAccount = new Map();
get options() {
return [
{ label: '5', value: '5' },
{ label: '10', value: '10' },
{ label: '15', value: '15' },
];
}

handleChange(event) {
this.pageSize = event.detail.value;
this.processRecords(this.items);
}

@wire(getAccounts, { searchKey: '$searchKey', sortBy: '$sortedBy', sortDirection: '$sortedDirection' })
wiredAccounts({ error, data }) {
this.loader = true;
if (data) {
this.loader = false;
this.processRecords(data);
this.error = undefined;
} else if (error) {
this.loader = false;
this.error = error;
this.data = undefined;
}
}

processRecords(data) {
this.items = data;
this.totalRecountCount = data.length;
this.totalPage = Math.ceil(this.totalRecountCount / this.pageSize);
this.data = this.items.slice(0, this.pageSize);
this.endingRecord = this.pageSize;
this.columns = columns;
}

//clicking on previous button this method will be called
previousHandler() {
this.isPageChanged = true;
if (this.page > 1) {
this.page = this.page - 1; //decrease page by 1
this.displayRecordPerPage(this.page);
}
var selectedIds = [];
for (var i = 0; i < this.allSelectedRows.length; i++) {
selectedIds.push(this.allSelectedRows[i].Id);
}
this.template.querySelector('[data-id="table"]').selectedRows = selectedIds;
}

//clicking on next button this method will be called
nextHandler() {
this.isPageChanged = true;
if ((this.page < this.totalPage) && this.page !== this.totalPage) {
this.page = this.page + 1; //increase page by 1
this.displayRecordPerPage(this.page);
}
var selectedIds = [];
for (var i = 0; i < this.allSelectedRows.length; i++) {
selectedIds.push(this.allSelectedRows[i].Id);
}
this.template.querySelector('[data-id="table"]').selectedRows = selectedIds;
}

//Method to displays records page by page
displayRecordPerPage(page) {
this.startingRecord = ((page - 1) * this.pageSize);
this.endingRecord = (this.pageSize * page);
this.endingRecord = (this.endingRecord > this.totalRecountCount) ? this.totalRecountCount : this.endingRecord;
this.data = this.items.slice(this.startingRecord, this.endingRecord);
this.startingRecord = this.startingRecord + 1;
}

sortColumns(event) {
this.sortedBy = event.detail.fieldName;
this.sortedDirection = event.detail.sortDirection;
return refreshApex(this.result);
}

handleKeyChange(event) {
this.searchKey = event.target.value;
var data = [];
for (var i = 0; i < this.items.length; i++) {
if (this.items[i] != undefined && this.items[i].Name.includes(this.searchKey)) {
data.push(this.items[i]);
}
}
this.processRecords(data);
}

onRowSelection(event) {
if (!this.isPageChanged || this.initialLoad) {
if (this.initialLoad) this.initialLoad = false;
this.processSelectedRows(event.detail.selectedRows);
} else {
this.isPageChanged = false;
this.initialLoad = true;
}

}

processSelectedRows(selectedAccounts) {
var newMap = new Map();
for (var i = 0; i < selectedAccounts.length; i++) {
if (!this.allSelectedRows.includes(selectedAccounts[i])) {
this.allSelectedRows.push(selectedAccounts[i]);
}
this.mapAccount.set(selectedAccounts[i].Name, selectedAccounts[i]);
newMap.set(selectedAccounts[i].Name, selectedAccounts[i]);
}
for (let [key, value] of this.mapAccount.entries()) {
if (newMap.size <= 0 || (!newMap.has(key) && this.initialLoad)) {
const index = this.allSelectedRows.indexOf(value);
if (index > -1) {
this.allSelectedRows.splice(index, 1);
}
}
}

}

showSelectedAccounts() {
if (this.allSelectedRows != null && this.allSelectedRows.length > 0) {
this.isModalOpen = true;
}
else {
alert('Please select account record..!!');
}
}

closeModal() {
this.isModalOpen = false;
}
}
ClientSidePagination.js-meta.xml
 <?xml version="1.0"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
<apiVersion>51.0</apiVersion>
<isExposed>true</isExposed>
<targets>
<target>lightning__AppPage</target>
<target>lightning__HomePage</target>
</targets>
</LightningComponentBundle>

Output:


LWC

 What are Lightning Web Components?

Ans: Lightning Web Components are an updated web standards-based framework method for creating lightning components on the Salesforce Platform.

  • Lightning Web Components utilize standard tech like CSS, HTML, and updated JavaScript without requiring a set of framework, incorporating latest innovations in JavaScript, including Shadow DOM, custom elements, and web components(ECMA Script 7 specially the updated JavaScript language used).
    • It Supports unit testing for quality assurance.
    • Standardized-based architecture, can build components for pages faster.
    • Code reuse is supported for quicker deployments.  
    • Natively supported in the browser So application's performance is faster.          


  • Similar to an AURA component, the main contents of a LWC are also HTML, JavaScript. There are optional content like CSS. But in addition to this LWC also has XML file which includes Metadata values for component.
LWC - Basic Concepts.

When ever we are going to create LWC we require 3 Files.
  • HTML File
    • Anything that we write in HTML File that should be included in the <template> </template> tag. It is the root tag in LWC for HTML
  • JavaScript File
    • lwc: The import statement imports Lightning Element from the LWC module.
    • Lightning Element : It is a custom wrapper of  standard HTML element.
    • export default : The Export default keywords exports a MyComponent class for other components to use.
  • Component Configuration File(Metadata i.e xml file)
    • target : Indicates where we can use the component such as Record Page, Home Page, App Page.
  • Decorators : 
    • @api : Expose a public property and methods decorate it with @api.
      • Public properties define the API for a component. An owner component that uses the component in it's markup can access the component's public properties.
      • Public properties are reactive. If the value of a reactive property changes, the component rerenders. When the component rerenders, all the expressions used in the template are reevaluated.
      • To communicate down the containment hierarchy, owner and parent components can call Javascript methods on child components.
    • @track : Track a private property, decorate it with @track
      • To Track a private property's value and rerender a component when it changes, decorate the property with @track. Tracked properties are also called private reactive properties.
    • @wire
      • It is built on Lightning Data Service which will be used to read Salesforce data and calling apex methods.
      • To read Salesforce data, Lightning web components use a reactive wire service. When the wire service provisions data, the component rerenders. Components use @wire in their JavaScript class to specify a wire adapter or an Apex method.
      • To use @wire to call an Apex method, we must set cacheable=true.
    Required Files in LWC.
    • Meta
      • Provides information about component
    • Javascript
      • Which has properties and logic
    • Template
      • Renders UI
Expose ApexMethods to Lightning Web Components
  • To expose an Apex mehod to a Ligtning web component, the method must be static and either   global or public. Annotate the method with @AuraEnabled. 
  •  Eg :  @AuraEnabled(cacheable=true)

                                    public static List<Contact> getContactList(){

                                                      return[SELECT Id,Name FROM Conatct]

                                           } 

How to import apex method

Syntax : 

import apexMethodName from '@salesforce/apex/Namespace.Classname.apexMethodReference';

  • apexMethodName : An imported symbol that identifies the Apex mehod.
  • apexMethodReference: The name of Apex method to import
  • Classname : The anme of Apex class.
  • Namespace : The namespace of the Salesforce organization. specify a namespace unless the organization uses the default namespace(c), in which case don't specify it.
  • @salesforce/apex : Scoped package (Scope -@ salesforce.package-apex)

          

Data Retrieval - imperative Apex method call

Imperative method is like an asynchronous method in JavaScript. It will be used for invoking the method which is annotated with cacheable=true also.           



HTML, JavaScript, CSS
  • HTML provides the structure for your component
  • JavaScript defines the core business logic and event handling
  • CSS provides the look, feel, and animation for your component.
The template tag is a fundamental building block of a component's HTML. It allows you to store pieces of HTML.

The export  statement defines a class that extends the LightningElement class. As a best practice,
the name of the class usually matches the file name of the JavaScript class, but it's not a requirement.

The import statement indicates the JavaScript uses the LightningElement functionality from the LWC module.

The connectedCallback() method is one of our lifecycle hooks.

Life Cycle hooks : Lifecycle Hooks - Salesforce Lightning Component Library

XML Configuration File Elements
  • Each lightning web component folder must include a configuration file named <component>.js-meta.xml. The configuration file defines the metadata values for the component, including targets and the design configuration for the Lightning App Builder and Experience Builder.    


Component Composition : Composition is Adding Component within the body of another component

  • Composition enables you to build complex components from simpler building-block components
How to refer child components name in parent components

1. childComponent      <c-child-component></c-child-component>

Replace Capital letter with small letter and prefixed with hypen

Try to avoid continuous capital letters in your component name.

What is DOM?
Ans : Document Object Model is a programming API for HTML and XML documents. It defines the logical structure of documents and the way a document is accessed and manipulated.

Basically, The DOM is a tree structure representation of web page.


What is Shadow DOM?
Ans : Shadow DOM brings encapsulation concept to HTML which enables you to link hidden separated DOM to an element.

Benifits of Shadow DOM- DOM queries, event propagation and CSS rules cannot go to the other side of the shadow boundary, thus creating encapsulation.


LWC LifeCycle Hooks

A Lifecycle hook is a callback method triggered at a specific phase of a component instance lifecycle

Mounting Phase 
  • constructor()
  • connectedCallback()
  • renderedCallback()
UnMounting Phase 
  • disconnectedCallback()
Error Phase
  • errorCallback()

Constructor Method 
  • This hook is invoked, when a component instance is created.
  • You have to call super() first inside this 
  • At this point, the component properties won't be ready yet.
  • To access the host element, use this.template
  • This method lifecycle flows from Parent to child component
  • We can't access child elements in the component body because they don't exist yet
  • Don't add attributies to the host element in the constructor
ConnectedCallback method
  • Called when the element is inserted into a document
  • This hook flow from parent to child.
  • You can't access child elements in the component body because they don't exist yet
  • You can access the host element with this.template.
  • Use it to : Perform initialization tasks, such as fetch data, setup caches, or listen for events (Such as publish-subscribe events)
  • Do not use : connectedCallback() to change the state of a component, such as loading values or setting properties. Use getters and setters instead
RenderedCallback Method
  • Fires when a component rendering is done
  • It can fire more than once
  • This hook flow from child to parent
  • When a component re-renders, all the expressions used in the template are reevaluated
Do not use renderedCallback()
  • To change the state or update property of a component
  • Don't update a wire adapter configuration object property in renderedCallBack(), as it can result in an infinite loop.
Unmounting phase
  1. disconnectedCallback Method
    • Fires when a component is removed from the DOM.
    • It flows from parent to child 
    • This callback method is specific to lightning web components, it is not from the HTML custom elements specification
Error phase
  1. errorCallback(err, stack)
    • This method is called when a descendant component throws an error in one of it's callback
    • The error argument is a JavaScript native error object, and the stack argument is a string
    • This callback method is specific to lightning web components, it is not from the HTML custom elements specification
Render Method
    Render is a method that tells the component which template to load based on some conditions. It always return the template reference
  • The render() method is not technically a lifecycle hook. It is a protected method on the LightningElement class. 
  • Call this method to update the UI. It may be called before or after connectedCallback()
  • It's rare to call render() in a component. The main use case is to conditionally render a template

Component Communication

Component Communication Approaches
  • Parent to Child Communication
  • Child to Parent Communication
  • Sibling Component Communication using Pubsub
  • Communication Across VF Pages, Aura and LWC Using Lightning Messaging Service
@api decorator
  • To make a field/property or method public, decorate it with @api decorator
  • When we want to expose the property we decorate the field with @api
  • An Owner component that uses the component in it's HTML markup can access the component's public properties via HTML attributes
  • Public properties are reactive in nature and if the value of the property changes the component's template re-renders
Parent to child Communication
  • Parent Component ---> Passing primitive, non-primitive, action data to child ---> Child Component
  • We need the variable to be decorated with @api to pass the data in Parent to Child Communication
Calling Child Method From Parent Component
  • Parent Component ---> Calling Child Method ---> Child Component


Child to Parent communication Approaches
  1. Child component ----> calling parent using simple event ---> Parent component
  2. Child component ----> calling parent using Event with data ----> Parent component
  3. Child component ----> event bubbling ----> Parent component
Note : When we want to communicate between child to parent we should know CustomEvents 

CustomEvent Syntax

            new CustomEent('event name',{bubbles:false, composed:false, details:null})

            Ex:  new CustomEvent('show', {bubbles:true, details:'hello'})
    • Event name is defined as 'show'
    • by default bubble and composed is  false but explicitly we made bubble as true for event bubbling
    • details is used to pass data with event and here i am passing 'hello'
dispatchEvent Syntax

            EventTarget.dispatchEvent(eventcreated)

            this.dispatchEvent(new customEvent('show',{bubbles:true, details:'hello'}))
    • 'this' is EventTarget
    • dispatchEvent trigger the CustomEvent
Event Name Naming conventions : Only string, No Uppercase letters, No spaces, Use underscores to separate words


Event Bubbling
    
    Lightning web components has only two event propagation
  • bubbles - A boolean value indicating whether the event bubbles up through the DOM or not. Defaults to false
  • composed - A Boolean value indicating whether the event can pass through the shadow boundary. Defaults to false

Setter Method

This method is use to modified the data coming from parent component.
If Object is passed as data to setter, to mutate the object we have to create a shallow copy


CSS Behaviour in Parent and child component

  • Parent CSS can't reach into achild component
  • A parent component CSS can style a host element(<c-child>)
  • A child component CSS can reach up and style its own host element
  • You can style to a element pass into the slot from the parent component only

Aura coexistence

  • Lightning Web Component and Aura Component can work together
  • Aura Components can contain Lightning web components. However, the opposite doesn't apply i.e Lightning web components can not contain Aura components.

Lightning Messaging Service

LMS is the first Salesforce Technology which enables you to communicate between Visualforce, Aura component and Lightning web component anywhere in lightning pages including utility components. 
  • In winter 20 salesforce released  "Lightning Message Service"    
In Salesforce we have three programming models to create UI 
  • Visualforce page (We can easily communicate between visualforce pages Ex: parent to child)
  • Lightning (We can easily communicate between Lightning components Ex: parent to child and vice versa )
  • Lightning web components(We can easily communicate between LWC components Ex : child to parent and parent to child)
There are some ways we can communicate between VF, Lightning, LWC but that are not standarized ways.
  • To Standardize the communication between VF, Aura, LWC Salesforce came across one feature called Lightning Messaging Service
  • This enables us to pass data from any component to any component(ex: VF to AURA, VF to LWC etc..)

LWC to LWC Communication Using LMS

1.Reference a Message channel in LWC

    import SAMPLEMESSAGE from "@salesforce/messageChannel/SampleMessageChannel__c"

2. Import LMS API

    import {APPLICATION_SCOPE, subscribe, unsubscribe, MessageContext } from 'lightning/messageService';

3. MessageContext wire Adapter is use to get information of all LWC using LMS

    @wire(MessageContext)
     Context

Syntax for Publish Method

        Publish(messageContext, messageChannel, message)
        Ex: publish(this.context, SAMPLEMESSAGE, message)

Syntax for Subscribe 

        subscribe(MessageContext, messageChannel, listener, subscriberOptions)
       


Salesforce Resources, Component Context and Notification 

Staic Resources : 

Import static resources from the @salesforce/resourceUrl scoped module. Static resources can be archieves(such as .zip and .jar files), images, style sheets, Javascript,  and other files.

import  myResource  from '@salesforce/resourceurl/resourceReference';

myResource : A name that refers to the static resource.

resourceReference : The name of the static resource. 

A Static resource name can contain only underscores and alphanumeric characters, and must be unique in your org. It must began with a letter, not include spaces, not end with an underscore, and not contain two consecutive underscores.

Third - party JavaScript Libraries in LWC

Syntaxt 

Import the Static Resource 

    import resourceName from '@salesforce/resourceUrl/resourceName';

Import methods from the platformResourceLoader

    import  {loadScript} from 'lightning/platformResourceLoader';

loadScript(Reference to the component, fileurl) : promise

Using Third Party CSS Library

*** First we need to upload the file in static resource

Syntax

Import the Static Resource 

    import resourceName from '@salesforce/resourceUrl/resourceName';

Import methods from the platformResourceLoader

    import  {loadStyle} from 'lightning/platformResourceLoader';

loadStyle(Reference to the component, fileurl) : promise

Content Asset Files

import content asset file from the @salesforce/contentUrl scoped module. Convert a Salesforce file into a content asset file to use the file in custom apps and community templates

Syntax : 

        import myContentAsset  from '@salesforce/contentAssetUrl/contentAssetReference';


Internationalization  Properties

Lightning web components have internationalization properties that you can use to adapt your components for users worldwide, across languages, currencies, and timezones.

In a single currency organization, Salesforce administrators set the currency locale, default language, default locale, and default timezone for their organizations. Users can set their individual language, locale, and timezone on their personal settings pages.

Syntax
    
    import  internationalizationpropertyname  from  @salesforce/i18n/internationlizationProperty 


Labels

import labels from the @salesforce/label  scoped module

Custom labels are text values stored in Salesforce that can be translated into any language that salesforce supports. Use custom labels to create multilingual applications that present information in a User's native language.

Syntax 

    import  labelName  from '@salesforce/label/labelReference';

Check Permissions 

    import Salesforce permissions from the '@salesforce/userPermission'  and '@salesforce/customPermission'  scoped modules

Syntax 

    import hasPermission from '@salesforce/userPermission/PermisssionName' ;

    import hasPermission  from '@salesforce/customPermission/PermisssionName' ;

Access Client Form Factor

    To access the form factor of the hardware the browser is running on, import the  @salesforce/client/formFactor scope module.

Syntax 

    import formFactorPropertyName from '@salesforce/client/formFactor' 

Possible values are 
    Large - A desktop client.
    Medium - A tablet client.
    Small - A Phone client
    

Get Information About Current User

    To get more information about the current user, use the @salesforce/user scoped module.

Syntax 

    import property from '@salesforce/user/property';

property supports only two properties 

Id - User's Id
isGuest - Boolean value indicating whether the user is a community guest user or not.

Fetch RecordId and Object Name

@api recordId - if a component with a recordId property used on a Lightning record page, the page sets the property to the  ID of the current  record.

@api objectApiName - If a component with an objectApiName property is used on a Lightning Record Page, the page sets the property to the API name of the current object


Navigation

Steps to use Navigation Service

In the component Javascript class, import the lightning/navigation module 

    import { NavigationMixin } from  'lightning/navigation';

Apply the NavigationMixin function to your component's base class

export default class myCustomElement extends  NavigationMixin(LightningElement) {}

To dispatch the navigation request, call the navigation service's 

[NavigationMixin.Navigate](pageReference, [replace])

pageReference - It is an object that defines the page
Replace - It is a Boolean values which is false by default. if this value is true it pageReference replaces the existing entry in the browser history

PageReference Types 

To navigate in Lightning Experience, Lightning Communities, or the Salesforce mobile app, define a pageReference object. 

These page reference types are supported.
  • App
  • Lightning Component
  • Knowledge Article
  • Login Page
  • Named Page(Communities)
  • Named Page(Standard)
  • Navigation Item Page
  • Object Page
  • Record Page
  • Record Relationship Page
  • Web Page

Navigate to New Record With Default Values

If we want default values then we need to import encodeDefaultFieldValues

import { encodeDefaultFieldValues }  from  'lightning/pageReferenceUtils'

we need to define the values in the method as shown in below

navigateToNewRecordWithDefault(){

    const defaultValues = encodeDefaultFieldValues({
             FirstName = 'Saikumar',
             LastName = 'Dharmavaram',
})
this[NavigationMixin.Navigate]({
     type : 'standard__objectPage',
     attributes : { 
             objectApiName : 'Contact',
             actionName : 'new'
},
    state:{
            defaultFieldValues : defaultValues
}

})
}



Lightning Data Service

Lightning Data Service is the prefered(and easiest) way to work with salesforce data. With LDS developers use Javascript to connect components to Salesforce data.

Lightning Data Service also provides security by making server calls to User Interface API endpoints. Using s client-side shared cache across all components, Lightning Data Service maximizes performance. When a record is cached, it's retrieved from the cache, eliminating unnecessary calls to the server. 

LDS maintains consistent, up-to-date data across multiple components and clients throughout the app lifeCycle. If several components use LDS to work with a record, and one of them updates the record, the other components automatically reflect that update.

Choose lightning-record-view-form  or lightning-record-edit-form when you need to customize the form layout, prepopulate field values, or change how record data is rendered


Lightning Data Service is a centralized data cacheing framework and it is built on top of User Interface API.
  • UI API gives you data and Metadata in a single response and also respect CRUD access, field level security settings, and sharing settings.
  • LDS displays only records and fields for which users have CRUD access and FLS visibility 
  • LDS caches results on the client 
  • LDS, Invalidates cache entry when salesforce data and metadata changes 
  • Optimizes server calls 

Base Lightning Components

    Base Lightning Components are built on Lightning Data Service. So, Lightning Data Service is used behind the scenes by base components and inherits its caching and synchronisation capabilities

There are three types of base lightning components built on LDS are
  1.   lightning-record-form
  2.   lightning-record-edit-form
  3.   lightning-record-view-form
When to use this form?
  • Create metadata-driven UI or form-based UI similar to the record detail page in Salesforce.
  • Display record values based on the field metadata
  • Hide or show localized field labels.
  • Display the help text on a custom field
  • Perform client-side validation and enforce validation rules.

Lightning-record-form

Use lightning-record-form component to quickly create forms to add, view, or update a record.

The lightning-record-form component provides these helpful features : 
  • Switches between view and edit modes automatically when the user begins editing a field in a view form
  • Provides Cancel and Save buttons automatically in edit forms
  • Uses the object's default record layout with support for multiple columns 
  • Loads all fields in the object's compact or full layout, or only the fields you specify
lightning-record-form is less customizable. To customize the form layout or provide custom rendering of record data, use lightning-record-edit-form(add or update a record) and lightning record-view-form(view a record).

Note : Whenever possible, to boost performance, define fields instead of layout. Specify a layout only when the administrator, not the component, needs to manage the provisioned fields.

Lightning -record-form key attributes

object-api-name : This attribute is always required. The lightning-record-form component requires you to specify the object-api-name attribute to establish relationship between a record and an object

Note : Event and Task objects are not supported 

record-id : This attribute is required only when you are editing or viewing a record.
fields : pass record fields as an array of strings. The fields display in the order you list them
layout-type : Use this attribute to specify a Full or Compact layout. Layouts are typically defined (created and modified) by administrators.

modes : This form supports three mode 
  • edit : creates an editable form to add a record or update an existing one. Edit mode is default when record-id is not provided, and displays a form to create new records.
  • view : Creates a form to display a record that the user can also edit. The record fields each have an edit button. view mode is the default when record-id is provided. 
  • readonly : Creates a form to display a record that the user can also edit 
Columns : Use this attribute to show multiple columns in the form.

Create a Record using lightning-record-form

Import references to Salesforce objects and fields from  @Salesforce/schema.

//Syntax
import objectName from  '@Salesforce/schema/objectReference';
import fieldName from '@Salesforce/schema/object.fieldReference';


Lightning  Data Service Wire Adapters and Functions

LDS Wire adapters are another way to work with Salesforce data. Use a wire adapter to read Salesforce data(records) and metadata (layout details, fields on an object, and so on). To use them, decorate a property or function with @wire and specify the wire adapter.

LDS wire adapters check the LDS cache first, and request data from the server only as needed.
Adapters react to change and refresh data accordingly. For example, when the parameter value changes, or other components modify data in the Lightning Data Service cache, an adapter provisions the new data to the wired property or function.
  1. Use this to get raw record data like picklist, recordInfo, objectInfo etc.
  2. Want more customization to create a forms 
  3. You want to perform business logics
The Wire adapters and JavaScript functions are available in lightning/ui* Api modules. Which are built on User Interface API. User Interface supports all custom objects and many standard objects.

Use Apex Methods with LWC

An Apex method used in a Lightning web component must be static, Public or global, and annotated with @AuraEnabled immediately before the method definition.

The @AuraEnabled annotation makes the Apex method available to Lightning components (both Lightning web components and Aura components).

Allowing the framework to cache data eliminates repeated server calls making future read operations run faster. We mark a method as cacheable by setting  cacheable = true in the @AuraEnabled annotation. 

Note : When a method is cacheable, newly added or changed versions of records may not be returned until the cache is refreshed

Note : Lightning Data Service is Unaware of the data that's cached by Apex methods. When an LDS function updates a record, that update has no impact on data that was cached by an Apex method.


What is @Wire Service?

  1. Wire service is built on Lightning Data Service
  2. LWC Component use @wire in their JavaScript class to read data from one of the wire adapters in the lightning/ui*Api namespace
  3. @Wire is reactive service
  4. The wire adapters defines the data shape that the wire service provisions in an immutable stream.

getObjectInfo

Use this wire adapter to get metadata about a specific object. The response includes metadata describing the object's fields, child relationships, record type, and theme.

import  { getObjectInfo } from ' lightning/uiObjectInfoApi ';


getPicklistValues

Use this wire adapter to get the picklist values for a specific field.

import { getPicklistValues }  from 'lightning/uiObjectInfoApi' ;

recordTypeId : The ID of the record type. Use the object info defaultRecordTypeId  property, which is returned from the getObjectInfo 

fieldApiName :  The API name of the picklist field

getPicklistValuesByRecordType

Use this wire adapter to get the values for every picklist of a specified record type

import { getPicklistValuesByRecordType }  from 'lightning/uiObjectInfoApi' ;


recordTypeId : The ID of the record type. Use the object info defaultRecordTypeId  property, which is returned from the getObjectInfo 

objectApiName : The Api Name of the Object

Note : If we have requirement of one or two picklist values then prefer getPicklistValues.  If we have more than two picklists then we will go for getPicklistValuesByRecordTypeId

getRecord 

Use this wire adapter to get the record's data 

import  { getRecord } from 'lightning/uirecordApi' ; 

recordId : The ID of the record type.
fields : A field or an array of fields to return
or
layoutType : it support two values Compact or Full(default)
Modes : used with layout. Values supported are Create, Edit and View(Default) 
optionalFields : a field name or an array of field names. If a field is accessible to the user, it includes in response otherwise it will not throw an error.

getFieldValue

Use this to get a field's  value from a record

import {getFieldValue} from lightning/uiRecordApi ;
getFieldValue(record : Record, field : string)

getFieldDisplayValue

Use this to get a field's value in formatted and localized format from a record 

import {getFieldDisplayValue} from lightning/uiRecordApi ;


getNavItems(Beta)

Use this wire adapter to retrieve the items in the navigation menu 

lightning/uiAppsApi  is for evaluation purpose only, not for production use.

 import {getNavItems} from 'lightning/uiAppsApi';


getRecordUi

Use this wire adapter to get layout information, metadata, and data to build UI for one or more records

*In this adapter we will get information of layout types and metadata, but in getRecord we will not get information of metadata and layouts.