Wednesday, 1 July 2020

Lazy loading in Lightning Web Component

 In this post we will talk about How to implement Infinity or lazy loading in Lightning Web Component using Lightning Datatable. Lazy loading helps you to load the data only when it is required. Infinite scrolling (enable-infinite-loading) enables you to load a subset of data and then load more data when users scroll to the end of the table.

In this post we will learn about lightning datatable attributes enable-infinite-loading and load more offset.
  • enable-infinite-loading : You can load a subset of data and then display more
    when users scroll to the end of the table. Use with the onloadmore event handler to retrieve more data
  • load-more-offset : Determines when to trigger infinite loading based on how many pixels the table's scroll position is from the bottom of the table. The default is 20
  •  onloadmore : The action triggered when infinite loading loads more data
In below image you can check the demo for Lightning Data Table With Lazy Loading. As we load data partially and once the user scrolls down at the end then we load the next set of data. So it is very responsive.


Lets see how we can implement the same.

Step 1) Apex Class with offSet


LazyLoadingController


public with sharing class LazyLoadingController {

    @AuraEnabled(cacheable=true)
    public static List<Account> getAccounts(Integer limitSize, Integer offset){
        List<Account> accountList = [SELECT Id,Name,Rating
                                     FROM Account
                                     ORDER BY CreatedDate
                                     LIMIT :limitSize
                                     OFFSET :offset
                                     ];
        return accountList;
    }
}
We will call same apex class from lightning web component.

Step 2) Lightning web component with Datatable


Create lightning web component in your sandbox or developer org. If you new please check this post how to create lightning web component in non-scratch org.

lazyLoadingLWCDemo.html

<template>
    <div style="height:500px">
    <lightning-datatable key-field="Id"
            data={accounts}
            columns={columns}
            enable-infinite-loading
            onloadmore={loadMoreData}
            hide-checkbox-column="true"
            show-row-number-column="true">
    </lightning-datatable> 
</div>
</template>
To enable infinite scrolling, specify enable-infinite-loading and provide an event handler using onloadmore.


lazyLoadingLWCDemo.js

import { LightningElement, track, wire } from 'lwc';
import getAccounts from '@salesforce/apex/LazyLoadingController.getAccounts';

const columns = [
    { label: 'Id', fieldName: 'Id', type: 'text' },
    { label: 'Name', fieldName: 'Name', type: 'text'},
    { label: 'Rating', fieldName: 'Rating', type: 'text'}
  
];

export default class LazyLoadingLWCDemo extends LightningElement {
    accounts=[];
    error;
    columns = columns;
    rowLimit =25;
    rowOffSet=0;
  
    connectedCallback() {
        this.loadData();
    }

    loadData(){
        return  getAccounts({ limitSize: this.rowLimit , offset : this.rowOffSet })
        .then(result => {
            let updatedRecords = [...this.accounts, ...result];
            this.accounts = updatedRecords;
            this.error = undefined;
        })
        .catch(error => {
            this.error = error;
            this.accounts = undefined;
        });
    }

    loadMoreData(event) {
        const currentRecord = this.accounts;
        const { target } = event;
        target.isLoading = true;

        this.rowOffSet = this.rowOffSet + this.rowLimit;
        this.loadData()
            .then(()=> {
                target.isLoading = false;
            });   
    }


}
We create connectedCallback function to load the initial data and then we are useing loadmoreData function to load more record from Apex base on offset. The onloadmore event handler retrieves more data when you scroll to the bottom of the table until there are no more data to load. To display a spinner while data is being loaded, set the isLoading property to true


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



Reference blog
  1. Datatable
  2. OffSet
Please share your feedback and let me know if this code can be improve.

Saturday, 27 June 2020

Salesforce Naming Conventions Best Practices

In this post we will talk about Salesforce naming conventions best practices and how to write a clean code. Salesforce naming convention is a rule to follow as you decide what to name your identifiers like class, variable, constant, method, etc. But, it is not forced to follow. So, it is known as convention not rule. Naming conventions make the application easier to read and maintain.

A well formatted code increases readability, understanding and ultimately maintainability of the code base.

Before staring with naming convention lets talk about What is PascalCase, camelCase, SNAKE_CASE ?
  1. camelCase :  Each word in the middle of the respective phrase begins with a capital letter. for example apexHours

    String firstName;
  2. PascalCase: It is same like Camel Case where first letter always is capitalized. for example ApexHours

    Class UserController{ }
  3. kebab-case: Respective phrase will be transferred to all lowercase with hyphen(-) separating words. for example apex-hours
    <c-hello-world-form></c-hello-world-form>
  4. SNAKE_CASE: Each word should be in capital with _ like . APEX_HOURS
    private static final Integer MY_INT;


Use Post Fix / Suffix:

Consistent file naming helps keep component easy to recognize and find. Here is some example of Postfix and Suffix we are using in our project from a long time.

Functional Type
Name Suffix
Examples
Trigger
Trigger
UserTrigger
Trigger Handler
TriggerHandler
UserTriggerHandler
Trigge Action
TriggerAction
UserTriggerAction
VF Controller
Controller
UserController
VF Controller Extension
Ext
UserExt
Service Class
Service
UserService
Model / Wrapper Class
Wrapper
UserWrapper
Web Service (SOAP)
Ws
UserToolsWs
Web Service (REST)
Rest
UserCreateRest
Email Service
EmlSvc
UserCreateEmlSvc
Asynchronous (Future)
Async
UserCreateAsync
Asynchronous (Batch)
Batch
UserCreateBatch
Scheduled Apex
Job
UserCleanupJob
Test Class
Test
UserCreateTest
Queueable Apex
Que
UserSyncingQue
Visualforce Page
-none-
UserClone
Visualforce Component
Cmp
UserCloneCmp
Lightning Components






APEX NAMING CONVENTION :

  1. Class Name :  Class names should be unique, beginning with an uppercase letter. It should NOT contain underscores or spaces (except from the prefix and suffix).  Class names should be nouns in mixed cases, with first letter of each interval word capitalized. For Example

    ClassNamePOSTFIX
  2. Variable Name : Variables should be in mixed case with a lowercase first letter. Internal words start with capital letters. Variable names should be short and sweet and meaningful. Its should be camelCase like accountList

    List<Account> accountList;
  3. Method Name : Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized. Whole words should be  used and use of acronyms and abbreviations should be limited. Name should be camelCase like  

    showAccountDetail();
  4. Constants : The names of variables declared class constants should be all uppercase with words separated by underscores (“_”). All uppercase letters in this format : CONSTANT_NAME Example: 

    private static final String ACCOUNT_LIMIT ='10';
  5. Trigger : <ObjectName>Trigger. This should follow Salesforce Trigger Patterns - One trigger per event per object

    UserTrigger


Visualforce Pages

This should PascalCase, No underscores or spaces and use whole words, limit acronym or abbreviation like below.
AccountClone


Lightning Web Components Naming Convention


Please check this post to leanr about LWC naming Convention.

  1. Html File :  Use camel case to name your component and use kebab-case to reference a component in the markup. For Example

    helloWorld.html
  2. JavaScript File : Java Script Class name should be in PascalCase like below example

    export default class HelloWorld extends LightningElement{
    }
  3. CSS File : Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized. Whole words should be  used and use of acronyms and abbreviations should be limited. Name should be camelCase like  

    showAccountDetail();

 

CSS Class Naming Standards

  • CSS classes should be named based on the component that is being addressed
  • Any name that is longer than one word, needs to be in this format : class-name
  • Multi word name should be separated by a " - "


Lightning Component

Lightning component names must be unique. They should begin with a lowercase letter. All components should end with the suffix “Cmp”. like  

userCardCmp (Initial lower case letter and suffixed with “Cmp” ) 

Lightning Events

Lightning event names must be unique. They should begin with a lowercase letter. All events should end with the suffix “Evt” . like   

userEvt (Initial lowercase letter and suffixed with “Evt” )

 

Check below recording to learn about how to write clean code in Salesforce.




Further learning