Friday, March 31, 2023

Wrapper Class in Salesforce

Wrapper Class in Apex Salesforce

In simple words, a wrapper class is a class inside a class. It is also known as a container class. It stores a group of similar or different data type variables into a single object.

Lets understand with an example:


public class ExampleCls {
    public class WrapperCls{
        public Boolean selected { getset;}
        public String record  { getset;}
        
    }
}

In this example, ExampleCls is the main class and
WrapperCls is the wrapper or the inner class.

This wrapper class contains two different data types,
one Boolean and other one is String

Use of Wrapper Class:

  1. It helps to stores a group of similar or different data type variables into a single object.
  2. We can use a wrapper class in Lightning Component when we need to send group of data from apex to lightning components.
  3. We can use Wrapper classes to parse the JSON request and response in REST API.

Wednesday, March 29, 2023

How to Check Custom Setting is List or Hierarchy in Apex

Today, we will learn how we can check whether the given custom setting is List of Hierarchy.

To Understand custom settings click here.

Apex Code:

String api = 'customSettingName__c';
Type reflector = Type.forName(api);
SObject sobj=(SObject)reflector.newInstance();
DescribeSObjectResult sobjResult = 
sobj.getSObjectType().getDescribe();
//some Name field info
SObjectField field = 
sobjResult.Fields.getMap().get('Name');
DescribeFieldResult fieldResult = 
field.getDescribe();
Integer length = fieldResult.getLength();
system.debug('length-'+length);

If length is 38 that means it is list, if length is 80 that means it is hierarchy


Please share your thoughts on this if there is any other way to do so.

Monday, March 27, 2023

What are Custom Settings in Salesforce

In Salesforce, custom settings are application metadata that offers a reusable set of static data that different departments in your company can access. 

Custom settings are classified into two types: 

  • Hierarchy Custom Settings
  • List Custom Settings 

The data in Hierarchy Custom Settings checks the organization, profile and user settings for the current user and makes the data visible for them accordingly. It uses a built-in hierarchical logic which lets you personalize settings for a specific user or a profile.

The data in List Custom Settings is directly visible to any user in the org. It provides a reusable set of static data which can be accessed across your organization.

Custom settings can be used to store a variety of data, such as configuration settings, feature switches, and business rules. They can be accessed using validation rules, workflows, Apex code, Lightning components, and the Salesforce API.


Advantages of Custom Settings

The main advantage of using Custom Settings is that the data is cached, which enables efficient access without the cost of repeated queries to the database. One doesn’t have to use SOQL queries which count against the governor limits.

Sunday, March 26, 2023

How to Hide a Div Tag Like a Toast Message in Lightning Web Components

Lets understand how we can hide a div like a toast message.

HTML File:

<div data-id="overview" class="red-bg">
  <lightning-formatted-text value={errorMsg}>
</lightning-formatted-text>
</div>

In this HTML file, we are creating a div element and will set a data-id

Data-id value will be used in the JS file to show or hide the div.

Js File:

We can call this hidemsg() method from the success of a server call.

This above div tag will be hidden after 5 secs

hidemsg(){
 setTimeout(() => {
this.template.querySelector('[data-id="overview"]').style.display 
='none';
  }, "5000")
}

When this hidemsg() is called, we can add setTimeout()

method will put a delay.

Saturday, March 25, 2023

Retry Mechanism Design in Salesforce

Lets understand a scenario to implement the Retry Mechanism in Salesforce.

Scenario:

There is a third party system which sends data to Salesforce and Salesforce processes that data and updates the objects. If there is a failure in update/insert then Salesforce system should retry to process them again. So, in such cases we can design the solution using the stage object.

Objects: 

Consider we want to do insert/update on Account based on the data received. For that, we can create a staging object lets say Accountstaging__c which will have fields similar to the Account object.

Design:

Using the standard APIs, third party system can send data to a staging table. There will no validation put in place when the data is being added to the staging object. This is done to assure that all the data reaches Salesforce system without any failure.

Salesforce then picks the data using a trigger or batch and performs the business logic and finally stores the data into Account Object.

Bulk Data Load to Salesforce:

This means when the other systems want to send data in bulk. In that case, we need to process all and update account object accordingly.

Lets say we are about to receive 10,000 records. We can discuss with the other system team and ask them to send a unique id for each bulk load and two extra records. One record will tell us that bulk data load has started to Salesforce and other record will tell that all the data has been sent. After this Salesforce can start its processing.

Record will come in this manner:

Begin of File(bof)-->Actual 10,000 records-->End of File(eof)

Here bof and eof are the checkboxes fields on the account stage object.

Data Processing:

We can have a trigger on stage object which will check whether the eof is true. If yes, then call the batch and query all the records using that unique id and process the data. At the end, we can mark the records in staging object as success or failed.

Retry Mechanism:

Consider some failures when doing the bulk updates in the system. We will have the list of failed records by querying all the failed records for that batch id.
These failed records can be retried using time based Process Builder to call the same batch class with a time gap or can call the batch class immediately by passing the list of records.

So based on the retry processing, we can update the stage records status as success or failure.

This mechanism can be done multiple times on the failed records if we add an integer field called retry counter on staging object. This field will be incremented by 1 whenever there is a failure. While doing the retry we can check whether the retry counter is less than 3, then only get the records. In this way the failed records can be retried multiple times.


If you have any thoughts on this, lets connect and discuss more this.








How to Query Salesforce Objects from External System Without Code

Sometimes, external system wants to get the latest data from Salesforce to run the business logic in their system. In those cases, external system can do a simple query Salesforce objects with the help of Salesforce Standard APIs. There is no code required from a Salesforce developer

Lets understand this concept with an example.

Consider Workbench as a external system. To query salesforce objects in workbench we need to follow the below pattern:

 /services/data/v20.0/query?q=SELECT+Id+,+Name+FROM+USER

where every element is concatenated by + operator

After the query is added click on Execute and once the response comes then click on Show Raw Data. It will open up the blue screen on the right.

workbench


  • totalsize attribute is the number of records returned.
  • At a time workbench can display 2000 records under raw response.
  • If the number of records returned are more than 2000 then NextRecordsUrl will be used to get next set of 2000 records.
  • Done Attribute under raw response tells whether we have reached the last page or not. 
  • If done = false then we need to NextRecordUrl to get next records.
  • If done = false, that mean there are no more records after this.

We can also write where clause in the query
SELECT+Id+,+Name+FROM+USER+where+id+=+'+00500xx+'
Similarly, we can add any filter in the query and get back the response.


Let me know your thoughts on this and we can discuss more.

Call Approval Process on Button Click in Salesforce LWC

In some scenarios, we may need to call the standard approval process on click of a custom button. So in that case, we can have a lightning quick action in LWC similar to one in Aura components.

Step 1:

Create an action for an object. Lets say Opportunity. We need to specify the LWC component name. for create a LWC component and enter that name in Lightning Web Component field.

approval


Step 2:

Add that action in the required page layout in the section as shown below:

approval


So the configurations are done...


Step 3:

Let's do the code part

Open that already created LWC component and add this code.

LWC html file:

<template>
    <lightning-quick-action-panel header="Submit for Approval">
        <lightning-textarea label="Comments" value={commentsonchange={commentChange
                                class="textAreaBody">
        </lightning-textarea>
        <div slot="footer">
            <lightning-button variant="neutral" class="slds-m-left_x-small" label="Cancel" 
                                onclick={closeAction}>
            </lightning-button>
            <lightning-button variant="brand" class="slds-m-left_x-small" label="Submit" 
                                onclick={handleSubmitClick>
            </lightning-button>
        </div>
    </lightning-quick-action-panel>
</template>

------------------------------------------------

LWC Js file:

import { LightningElement,wire,track,api } from 'lwc';
import submitApproval from '@salesforce/apex/OppApproval.submitApproval';
import { CloseActionScreenEvent } from "lightning/actions";
import { CurrentPageReference } from 'lightning/navigation';

export default class OppApprovalLWC extends LightningElement {
@track comments;
@api recordId;

closeAction() {
    this.dispatchEvent(new CloseActionScreenEvent());
    }
@wire(CurrentPageReference)
    getStateParameters(currentPageReference) {
        if (currentPageReference) {
            this.recordId = currentPageReference.state.recordId;
        }
    }
commentChange(event) {
        this.comments = event.detail.value;
    }

handleSubmitClick(event){

        submitApproval({ oppId: this.recordId, comments: this.comments})
        .then(result =>{
            eval("$A.get('e.force:refreshView').fire();");
            this.dispatchEvent(new CloseActionScreenEvent());
        })
        .catch(error =>{
            
        });
        
    }
}

-------------------------------------------------

LWC Meta XML file:

<?xml version="1.0"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>54.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordPage</target>
        <target>lightning__RecordAction</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordAction">
        <actionType>ScreenAction</actionType>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>


-------------------------------------------------

Apex Class:


public class OppApproval {

 @auraEnabled

    public static void submitApproval(String oppId,String comments){
        try{
            Approval.ProcessSubmitRequest approvalRequest = new Approval.ProcessSubmitRequest();                
            approvalRequest.setObjectId(OppId);
            approvalRequest.setComments(comments);
     approvalRequest.setSkipEntryCriteria(true);
                Approval.ProcessResult approvalResult = Approval.process(approvalRequest);
                if(approvalResult .isSuccess()){
                    system.debug('success-'+approvalResult .isSuccess());
                }
                else{
                    system.debug('failed-'+approvalResult .isSuccess());
                }
            
        }
        catch (Exception e) {
            
            String errorMsg = e.getMessage();
            throw new AuraHandledException(ErrorMsg);
        }
        
    }
}

Salesforce Integration Design Patterns

Here are some of the integration patterns available in Salesforce:

1. Request-Reply: In this pattern, Salesforce sends a request to another system, and the other system responds with a reply. This pattern is useful when you need to get data from another system, or when you need to update data in another system.

2. Fire & Forget: Salesforce invokes a process in a remote system but doesn’t wait for completion of the process. Instead, the remote process receives and acknowledges the request and then hands off control back to Salesforce.

2. Batch Data Synchronization: In this pattern, data is exchanged between two systems periodically in batches. This is useful when large volumes of data need to be transferred between systems.

3. Data Virtualization: Salesforce accesses external data in real time. This removes the need to persist data in Salesforce and then reconcile the data between Salesforce and the external system

4. Middleware Integration: This pattern involves using middleware such as MuleSoft or Dell Boomi to connect systems. Middleware can help to manage the complexity of integrations by providing features such as data transformation, routing, and error handling.

5. Point-to-Point: This pattern is used when you need to connect Salesforce with a single system. Point-to-point integration can be simple to set up and maintain, but it can become complex if you need to connect Salesforce with multiple systems. 

Overall, the integration pattern you choose will depend on the complexity of the integration, the volume of data being transferred, and the real-time requirements of your business processes.

These patterns can be used individually or in combination to create a comprehensive integration strategy for your organization. The choice of pattern will depend on the specific requirements of your integration project.


Let me know your thoughts in the comment section!!

Sunday, March 19, 2023

What are Named Credentials in Salesforce? What are its Benefits

Let us understand what are Named Credentials in Salesforce and what are its Benefits

Using Named Credential, we can make call out to external system without supplying username or Password
A named credential specifies the URL of a callout endpoint and its required authentication parameters in one definition. To simplify the setup of authenticated callouts, specify a named credential as the callout endpoint.

Why Avoid Hardcoding Credentials :

  1. It is a Maintenance nightmare. Having Credentials hardcoded means you have to deploy the changes every single time like when your password changes or expires.
  2. It is also difficult to maintain changes in a different environment
  3. Not very secure.

Benefits of using Named Credentials :

  1. Authentication is done by Salesforce and you need not to worry about that.
  2. Easy for admins to maintain.
  3. Secure storage of credentials.
  4. No need to create a Remote Site Setting if using a Named Credential.
  5. The callout is easier to maintain. No hard coding involved.

Apex HTTP Callout Without Named Credential:

HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setEndpoint('https://example .com/path/my/api');
String username = 'username';
String password = 'password';
//Add basic authentication header to the callout
Blob headerValue = Blob.valueOf(username + ':' + password);
String authHeader = 'BASIC ' + EncodingUtil.base64Encode(headerValue);
req.setHeader('Authorization', authHeader);
Http h = new Http();
HttpResponse response = h.send(req);
System.debug('response-'+ response);

Apex HTTP Callout With Named Credential:

HttpRequest req = new HttpRequest();
req.setMethod('POST');
req.setEndpoint('callout:Sample_API/some_path');
//No need to manually set any headers here. Salesforce will add this for us automatically.
Http http = new Http();
HTTPResponse response = http.send(req);
System.debug('response-'+ response);

Saturday, March 18, 2023

What is Master Label Tag in LWC Meta File

Master label is a custom name given to a lightning web component. Developers can given user-friendly name and that name will be visible in the Lightning App Builder and in Experience Builder.

Sample meta.xml code-

<apiVersion>42.0</apiVersion>
<isExposed>true</isExposed>
<masterLabel>MyLWCComponent</masterLabel>
<targets>
    <target>lightning__RecordPage</target>
    <target>lightning__AppPage</target>
    <target>lightning__HomePage</target>
</targets>


So next time when you add a lightning component in a page, search Master Label(MyLWCComponent) in App builder.

Let me know your thoughts in the comment section!!

Friday, March 17, 2023

With sharing & Without sharing keywords in APEX

With sharing & Without sharing keywords in APEX


With sharing Keyword:

This keyword enforces sharing rules that apply to the current user. If absent, code is run under default system context. Use the with sharing keywords when declaring a class to enforce the sharing rules that apply to the current user. Use With Sharing when the User has access to the records being updated via Role, Sharing Rules, Sales Teams – any sort of sharing really.

Example:

public with sharing class sharingClass {

// Code here

}

Without sharing keyword:

Ensures that the sharing rules of the current user are not enforced. Use the without sharing keywords when declaring a class to ensure that the sharing rules for the current user are not enforced. For example, you may want to explicitly turn off sharing rule enforcement when a class acquires sharing rules when it is called from another class that is declared using with sharing. Without Sharing is reserved for cases where the User does not have access to the records, but there is a need to update them based on user input.

public without sharing class noSharing {

// Code here

}

Some things to note about sharing keywords:

  • The sharing setting of the class where the method is defined is applied, not of the class where the method is called. For example, if a method is defined in a class declared with with sharing is called by a class declared with without sharing, the method will execute with sharing rules enforced.
  • If a class isn’t declared as either with or without sharing, the current sharing rules remain in effect. This means that the class doesn’t enforce sharing rules except if it acquires sharing rules from another class. For example, if the class is called by another class that has sharing enforced, then sharing is enforced for the called class.
  • Both inner classes and outer classes can be declared as with sharing. The sharing setting applies to all code contained in the class, including initialization code, constructors, and methods.
  • Inner classes do not inherit the sharing setting from their container class.
  • Classes inherit this setting from a parent class when one class extends or implements another.

Please share the blog and leave a comment about your thoughts.
Click here for more blogs.

Thursday, March 16, 2023

Understand Salesforce Integration and HTTP Methods

What is Salesforce Integration?

Salesforce integration is the process of merging the data and functionality of Salesforce with another application to provide users with a single unified experience. It allows you to provide your team with an ideal mix of features pertaining to both platforms.

These classes expose the HTTP request and response functionality.

Http Class: Use this class to initiate an HTTP request and response.

HttpRequest Class: Use this class to programmatically create HTTP requests like GET, POST, PATCH, PUT, and DELETE.

HttpResponse Class: Use this class to handle the HTTP response returned by HTTP.


Most common HTTP methods:

1. GET : The GET method is used to retrieve information from the given server using a given URI. Requests using GET should only retrieve data and should have no other effect on the data.

2. POST : A POST request is used to send data to the server and create the record.

3. PUT : PUT is used to send data to a server to create/update a resource. Replaces all the current representations of the target resource with the uploaded content.

4. PATCH : PATCH is used to update partial resources. For instance, when you only need to update one field of the resource, PUTting a complete resource representation might be cumbersome and utilizes more bandwidth.

5. HEAD : HEAD is almost identical to GET, but without the response body. HEAD transfers the status line and the header section only.

6. DELETE : The DELETE method deletes the specified resource.

7. OPTIONS : The OPTIONS method describes the communication options for the target resource. 


public class AuthCallout {
    public void basicAuthCallout(){
    HttpRequest req = new HttpRequest();
    req.setEndpoint('http://www.yahoo.com');
    req.setMethod('GET');
    // Specify the required user name and password to access the endpoint
    // As well as the header and header information
    String username = 'myname';
    String password = 'mypwd';
    Blob hValue = Blob.valueOf(username + ':' + password);
    String authorizationHeader = 'Basic ' +EncodingUtil.base64Encode(hValue);
    req.setHeader('Authorization', authorizationHeader);
    // Create a new http object to send the request object
    // A response object is generated as a result of the request
    Http http = new Http();
    HTTPResponse res = http.send(req);
    System.debug(res.getBody());
    }
 }


Please share the blog and leave a comment about your thoughts.
Click here for more blogs.

Chain Batch Jobs in Salesforce

How to Chain Batch Jobs in Salesforce

First of all, we need to understand why do we need to chain the batch jobs?

Lets take an example:

We have two requirements to do in code. First we need to delete all the contacts and then insert the new contacts received from Integration. In this case, we can have two batch jobs. First job will delete the contacts and then second job will insert the new contacts.

In other words, Chaining jobs is useful if your process depends on another process to have run first. 

Call another batch in finish method so that all the processing of first job is completed and system will have the updated data before the second job.

global class MyBatchClass implements Database.Batchable<sObject> {
    global Database.QueryLocator start(Database.BatchableContext bc){
        // collect the batches of records
    }
    global void execute(Database.BatchableContext bc, List<P> records){
        // process each batch of records
    }  
    global void finish(Database.BatchableContext bc){
        // call the other batch in finish method.    
        secondBatchJob obj = new secondBatchJob();    
        database.executeBatch(obj,<batch size>);
    }  
}    

Please share the blog and leave a comment about your thoughts.

Click here for more blogs

Monday, March 13, 2023

Iterable Batch Apex Salesforce

        Iterable Batch Example

If your logic is based on rows from an SObject then the Database.QueryLocator is the way to go as that allows the batchable to query very large numbers of records.

But sometimes you may want to do some work that isn't directly related to SObject rows. In that case the iterable object can simply be an array/list:

public class ExampleBatchApex implements Database.Batchable<String>{
public Iterable<String> start(Database.BatchableContext BC){
    return new List<String> { 'When', 'shall this' , 'quarantine be over' };
}
public void execute(Database.BatchableContext info, List<String> strList){
    //let’s do something with the string for fun
    String myStr = strList[0];
}
public void finish(Database.BatchableContext info) { }
}

// executing the batch apex
Id jobId = Database.executeBatch(new ExampleBatchApex());

Monday, March 6, 2023

Resolve Error 'Unable to lock row' in Salesforce

How to Resolve Unable to lock row error in Salesforce

When a record is being updated or created, Salesforce places a lock on that record to prevent another operation from updating the record at the same time and causing inconsistencies on the data.

Record locking errors is a common source of headache for people coding Data Migrations or Integrations with Salesforce. The good news is that most of the time It's our own integration code that is causing self-contention as opposed to some other user locking the record on us (because we are plowing too many conflicting updates at once, usually in an effort to improve performance). It can also be caused by Salesforce code that is triggered by our updates that require the locks, and then, when not getting them, ultimately fail. Then, that error bubbles up and our updates fail.

Lets walk through an example:

  1. User A imports a task via the data loader and assigns it to an existing account record. When the task is inserted, the apex trigger is fired.
  2. Just 2 seconds after User A starts the insert via the data loader, User B is manually editing the same account record the task is related to.
  3. When User B clicks Save, internally we attempt to place a lock on the account, but the account is already locked so we cannot place another lock. The account had already been locked by the creation of the Task.
The 2nd transaction then waits for the lock to be removed. Because the task takes about 14 seconds to be created, the lock is held for 14 seconds. The second transaction (from User B) times out, as it can only wait for a maximum of 10 seconds.

To prevent this, you can do either of the following:

  • Reduce the batch size
  • Process the records in Serial mode instead of parallel, that way one batch is processed at a time.
  • Sort main records based on their parent record, to avoid having different child records (with the same parent) in different batches when using parallel mode. 
  • Check for overlapping schedules, 2 schedules updating the same object should not start at the same time if possible.

Please share the blog and leave a comment about your thoughts.

Click here for more blogs

How to cover code for catch block in Apex

Sometime developer needs to cover the catch part in the Apex Class.

Code Snippet:

try{
    Account acc = new Account();    
    acc.Name = 'Test';    
    Database.insert (tempList,false);
}
catch(exception e){
    LogObj obj = new LogObj();
    obj.error = e.getMessage();
    insert obj;
}

To cover the catch, we can modify the code as shown:

try{
    boolean allOrNone = false;
    Account acc = new Account();    
    acc.Name = 'Test';    
    Database.insert (tempList, allOrNone );
    if(Test.isRunningTest()){
        Database.insert (tempList, 0);
    }
}
catch(exception e){
    LogObj obj = new LogObj();
    obj.error = e.getMessage();
    insert obj;
}

In this case, code will run the Database.insert (tempList, 0); line and will eventually fail and code will go to catch block.

Please share the blog and leave a comment about your thoughts.

Click here for more blogs