LET'S LEARN TOGETHER. THE BEAUTIFUL THING ABOUT LEARNING IS NOBODY CAN TAKE IT AWAY FROM YOU.

Winter '21 Apex New Feature

 


This post will cover some of my favorite Apex new features from Winter '21. I have published another post that covered new existing enhancements for Flow Designer. To explore all the new features from Winter '21 release, I highly recommend -
  • Sign up to a pre-release org and explore all the new features.
  • Post your findings in the Trailblazer Community and include the hashtag #Winter21Treasure to receive Trailhead Treasure Hunter badge
Here is the list

Safe Navigation Operator

Share:

Winter '21 Flow Enhancements

 


Winter '21 pre-release org is ready. And without any surprise, Winter '21 is also bringing lots of great enhancements. In this post, I am going to focus on a few Flow Enhancements that we will be getting soon and will be able to take advantage of. 

Handling Deletion Through Record Triggered Flow

Share:

Show Your Data in Datatable, Map or Tile Format Inside Flow


In this post, I am going to show you one of the most powerful AppExchange flow solutions built by Salesforce Labs. If you ever needed to display a collection of records in some format, mostly in datatable format to the user and provide options to the user to select records from that list and finally perform some actions based on those selected records, then this AppExchange pre-built flow solution is your going to be your friend. ūüėÉ

The name of the solution is Flow Datagrid Pack. With this solution, you have the power now to display your collection of records in three different formats -

  • Data Grid - Basically displays the records in a multi-select datatable.
  • Tile Grid - Displays in multi-select (configurable) tiles format.
  • Map Grid - Displays multi-select markers on map where you need to display records on the map. Ex: Display a list of accounts in Ontario within the map.
Let's configure this flow solution for a basic use case.

Use Case:

Need a solution where all the contacts from an account will be displayed in datatable and the user can select from the list. Based on the selected contacts, only those contacts should be displayed on the next screen.

Solution - Flow:

I build the below flow using the Flow Datagrid pack.

Here are the steps -

Fetch Associated Contacts

In this step, I am fetching all the contacts associated with an account.

Loop Through All Contacts and Store Contact Ids

Here I am looping through all the contacts and storing their ids in a collection variable. This step is needed as a collection variable with record ids are needed in the Flow Datagrid Pack to display the records. 
Note - I am not sure why this extra loop is required, but my initial thought is that this loop can easily be removed and Flow Datagrid Pack should work on the collection of records.


Display All Contacts in Datatable

Here I am using the Flow Datagrid Pack pack as displayed below.
To start with, I am just using the basic input parameters, but you can configure a lot. The details level of the configuration details, you can get to know from here.
  • ID List: Here I am using the collection variable I have created in an earlier screen which stores all the contact ids.
  • Object API Name: I am using Contact here as object name. You can literally work on any standard or custom objects. Note - With External objects, this solution is not working as of today.
  • Field API Names: I am using the API names of the fields which I would like to display inside the datatable.

Display Selected Contacts

In this step, I am displaying the selected records using the same Flow Datagrid Pack. 
The difference is that here in the ID list I am using the auto-generated collection variable from the previous screen which stores the id of only selected contacts.



This is how the flow will look like -

That's all!! Isn't it super easy? I highly recommend everyone to try this one. 

Note - To get all the pre-built cool Flow solution check the dedicated flow section in AppExchange. Link

Share:

Spring'20 Brings Improved Code Coverage Result for Apex Test Class

 

Writing test classes to cover both positive, negative, and bulkified scenarios are always the best practices that each developer should follow. While writing test classes, our approach should be to cover as much as code and all the scenarios. There is a restriction from Salesforce that if there is not enough coverage (75%) for the code, then Salesforce will not allow you to deploy your code to production.

So identifying the code coverage is very important. Now there are multiple ways we can get to know the code coverage like - Setup menu, Developer Console, SOQL Query, Salesforce CLI, or Salesforce extension in Visual Studio Code. With so many options there comes the difficulties. Each option presents the code coverage in a different way and more importantly, each option calculates code coverage in a different way. This always creates confusion. For example, when a developer writes the test class and executes that from CLI, it provides the code coverage, let's say 90%, which should be good enough to deploy the code into Production. But while deployment, the code coverage came down to 50%, and thus deployment stops. The reason for this drop in code coverage is that while deploying code coverage is calculated at the org level i.e. percentage of coverage for that class across the org.

To solve this problem, Salesforce comes up with the Enhanced Code Coverage option. With this option, developer will get - 

  • Different classes being covered by the test class. The percentage of each class covered and uncovered lines from each class.
  • Test result which will pass/fail result for each test method.
  • Finally Test Summary will show "Test Run Coverage" and "Org Wide Coverage".
This change was introduced in Spring 20 release. You can read more about it - https://releasenotes.docs.salesforce.com/en-us/spring20/release-notes/rn_sf_cli_code_coverage_apextests.htm

In order to use this feature in Salesforce CLI, the first thing you need to do is set up your environment variable.

Setting up the environment variable

There are three ways to do that. 
You can do that for a single command by doing 

SFDX_IMPROVED_CODE_COVERAGE=true sfdx force:apex:test:run ...

or set it for a shell session with

export SFDX_IMPROVED_CODE_COVERAGE=true

or if you want to set it permanently, then set it in the config file for your shell/command prompt.

Setting up the environment variable is important as it will eliminate Developer Console and VS Code/CLI code coverage mismatch.

Running the test

Once the environment variable is set up, you can run your test by -

sfdx force:apex:test:run -n "CommunicationHandlerTest" -c -r human

Here I am trying to execute the test class - CommunicationHandlerTest. To know more about the options, read - https://github.com/forcedotcom/salesforcedx-vscode/issues/2224

The result will be something like this 

I highly recommend everyone to use this new feature. Thank you.

Share:

Spring'20 brings one Invocable method for all

 

Have you ever asked this question to yourself - Why I have to write multiple invocable methods for the same functionality working on different objects? Definitely not a very clean approach. Thankfully Salesforce came up with the enhanced version of Invocable methods which now can work on multiple objects doing similar types of work. 

With this new enhancement, you can now write Invocable methods which will accept generic sObject data type. As a result, you will write one single Invocable method which will now work for multiple sObjects. The advantage is that if in your org, you have multiple Invocable methods doing similar operations (you just created them because they need to work on different sObjects), it the time to merge them to make a single Invocable method and make your org look clean.

In this post, I am going to show the example of creating one Invocable method which will be used to create Lead and Account when calling from different flows.

Here is the Invocable method:

public class createRecords {
@InvocableMethod(
label = 'Create Records'
description = 'Update records or create new records')
public static List<myResponse> createRecords(List<myRequest> request){
List<SObject> records = new List<SObject>();
for(myRequest singleRequest : request){
records.addAll(singleRequest.records);
}
List<myResponse> response = new List<myResponse>();
myResponse singleResponse = new myResponse();
Schema.SObjectType sObjectType = records.get(0).getSObjectType();
if(sObjectType != null){
String listType = 'List<'+sObjectType+'>';
List<SObject> castRecords = (List<SObject>)Type.forName(listType).newInstance();
castRecords.addAll(records);
upsert castRecords;
singleResponse.records = castRecords;
response.add(singleResponse);
}
return response;
}
public class myRequest {
@InvocableVariable(label = 'Records to create')
public List<SObject> records;
}

public class myResponse {
@InvocableVariable(label = 'Inserted/Upserted records')
public List<SObject> records;
}
}

As you can see, this above Apex code is written in such a way that it can work on any sObjects. In the actual Invocable method, we are typecasting the input records (myRequests -> records) to the actual sObject.

Below are two flows from where I am going to call this Invocable method passing the type of sObject against which the function needs to work.

Account Create Flow



Lead Create Flow




As you can see in both the flows, I have used the same Invocable method, just method the sObject name against which it will operate. I think this enhancement is going to make development very clean, reducing the surface area od code maintenance and increasing code reusability. 
Share:

Configure Parcel in VS Code for JavaScript Development


In my previous posts, I have written down the steps which will help you to configure ESLint, Prettier, and Husky in Visual Studio Code to make your JavaScript development easy and making sure code syntax, as well as best practices, are being followed. 

If you haven't seen that post, I highly recommend you go through that at - 

Configure ESLint and Prettier in VS Code for JavaScript Development

Configure Husky in VS Code for JavaScript Development

Today I am going to talk about another important tool when you are dealing with creating packages for your JavaScripts project. It's called Parcel.

From this post, you can expect -
  • Quick introduction of Parcel
  • Configure Parcel in Visual Studio Code
  • Examples


Quick Introduction of Parcel

Parcel is a web application bundler. It's an alternative of webpack and comes with some different value propositions.
The main features which come with Parcel are - 

Parcel makes sure to perform all the above without any configurations with speed. Pretty impressive, right. 

Configure Parcel in Visual Studio Code

Step 1 - Initiate npm

We can initiate npm by executing the command "npm init" from the terminal section of the Visual Studio Code. This will ask for a few questions which are very self-explanatory, but we can ignore them by just typing enter. Once the command executes, it will create the file package.json in the workspace.


Step 2 - Install Parcel

We can install parcel as dev dependency by executing the command "npm install -D parcel-bundler" from the terminal section of the Visual Studio Code. Once done, the package.json should add parcel as dev dependency like shown below - 
{
"name": "parcel-laerning",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"parcel-bundler": "^1.12.4"
}
}


Step 3 - Update Scripts

In this step, we need to write the scripts which will execute parcel. With the assumption that index.html is the starting point of our application and it is inside a folder named src, we can write down the below two scripts. Dev script is for the development environment and prod is for your prod environment. 
{
"name": "parcel-laerning",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "parcel src/index.html",
"prod": "parcel build src/index.html"
},
"author": "",
"license": "ISC",
"devDependencies": {
"parcel-bundler": "^1.12.4"
}
}
Parcel comes with a built-in development server, which is a big advantage as we no longer needed to set up our local server to run your project. Different scripts for dev and prod will make sure that we will do all our testing in development environment first and when things look good, then only we will create your production bundle. Production bundle will disable hot module replacements and also doesn't watch for the changes in real-time

We can get all the parcel CLI commands at https://parceljs.org/cli.html

Basically, that's all we need to start using Parcel.

Examples

We will create below files (contents of each file will be given) as shown in the picture below -


main.css

body {
background-color: yellow;
}


calculate.js

const doAddition = (x, y) => {
var result = x + y;
console.log("Addition : " + result);
};

const doMultiplication = (x, y) => {
var result = x * y;
console.log("Multiplication : " + result);
};

export { doAddition, doMultiplication };


main.js

import "./../css/main.css";
import { doAddition, doMultiplication } from "./calculate.js";

doAddition(10, 20);
doMultiplication(10, 5);


index.html

<!DOCTYPE html>
<html lang="en">
<head>
<title>Testing Parcel</title>
<script src="js/main.js" defer></script>
</head>

<body>
Hello from Sudipta
</body>
</html>

Now we can execute the below command from the terminal which will create the server and if you inspect then we will see the result of addition and multiplication function being printed in the console.

We can see the result by typing the URL (highlighted above) [Note - URL can be different for you] in the browser window and by console should display the result as shown below -

In my next post, I am going to share how we can configure jest and perform testing of our JavaScript code. Till then happy learning.
Share:

How to restrict @AuraEnabled method access for Authenticated users



As we all know security is always the number 1 priority for Salesforce, so there is a critical update coming to all of our Salesforce environments. This will change the way we provide access to AuraEnabled Apex methods. 

From this post, you can expect -
  • What problem this update is going to solve?
  • When can we expect this update in our environments?
  • Show me the problem
  • Show me the solution(s)
  • Show me all the places where I need to make this change


What problem this update is going to solve?

When we write our Lightning Component or Lightning Web Component today, for any type of server operation, we write Apex classes and annotate the method with @AuraEnabled. We don't have an option today to restrict the access to our AuraEnabled methods today. 

That is why Salesforce came up with this important critical update where you need to specify who can access your AuraEnabled methods. I will explain this update with one example later in this post.


When can we expect this update in our environments?

This update "Restrict @AuraEnabled Apex methods to authenticated users" came as part of Salesforce's Winter '20 release. Enforcement will start on August 9th, 2020.


Show me the problem

Let's say we have this below Lightning Web Component where we pass a string to the AuraEnable controller class and then class return list of Contacts. Finally component is going to display the list of contacts. Below is the code -
import { LightningElement, track } from "lwc";
import serachContacts from "@salesforce/apex/ContactSearchController.retriveContacts";

// datatable columns
const columns = [
{
label: "Name",
fieldName: "Name",
type: "url",
typeAttributes: { label: { fieldName: "Name" }, target: "_blank" }
}
];
export default class CustomSearchInLWC extends LightningElement {
@track searchData;
@track columns = columns;
@track strSearchProdName;

handleContactName(event) {
this.strSearchContactName = event.detail.value;
serachContacts({ strContactName: this.strSearchContactName })
.then((result) => {
this.searchData = result;
})
.catch((error) => {
console.error(error);
});
}
}


Apex Class - ContactSearchController
public with sharing class ContactSearchController {
@AuraEnabled(Cacheable=true)
public static List<Contact> retriveContacts(String strContactName) {
strContactName = '%' + strContactName + '%';
List<Contact> allContacts = [
SELECT Id, Name
FROM Contact
WHERE Name LIKE :strContactName
];
return allContacts;
}
}


This is how the Lightning Web Component will look like -












This setup will work until we enable the below critical update, which you can find under 
Setup -> Release Updates (Beta)

Now if we enable this update and try to access the same page again, we will see the below error in the console window -

From the message, it is very much clear that the user is not having access to ContactSearchController.

Show me the solution(s)

We have two options in today. Either give the permission in the user's profile level or assign permission sets(selecting the Apex class permission there) to users.

Show me all the places where I need to make this change

Salesforce came up with an unlocked package, named @AuraEnabled Scanner, which you can install by -- https://<myDomain>.lightning.force.com/packaging/installPackage.apexp?p0=04tB0000000ZQHxIAO, where <myDomain> is the name of your custom Salesforce domain.

Once installed, open the app by typinhttps://<myDomain>.lightning.force.com/c/AuraEnabledScanner.app You need to have AuraEnabled Scanner User permission set assigned to you so that you can access this app. 

App will show you all the places where you need to make this change like shown below -

Hope that this post will be helpful. Thank you.
Share:

Never miss a post. Subscribe to get latest blog posts, right into your email box.

* indicates required

Labels

Salesforce (105) Apex (52) admin (28) visualforce (21) ADM (20) dev 501 (19) lightning (19) integration (18) learn salesforce (18) 501 (16) javascript (14) SOAP (13) tutorial (11) Advanced Apex (10) Certification. (10) Kitchener Developer Group (8) Trigger (8) test class (8) Certification (7) flow (7) security (7) unit testing (7) Advanced Admin (6) Lightning Experience (6) SOQL (6) Sharing and Visibility (6) design pattern (6) developer (6) report (6) salesforce release (6) service cloud (6) trailhead (6) use case (6) Lightning Feature (5) New Features (5) css (5) dashboard (5) debug (5) formula (5) mobile (5) solution management (5) JSON (4) Kitchener User Group (4) Knowledge Management (4) Lightning Web Component (4) New Feature (4) Sales Cloud (4) Salesforce DX (4) Tips (4) WebSphere (4) best practice (4) cast iron (4) component (4) deployment (4) event (4) github (4) html (4) map (4) polymer (4) profiles (4) release (4) responsive (4) tdd (4) ui (4) visual studio code (4) Architect (3) Article (3) Live Chat (3) Online Event (3) Opportunity (3) Performance (3) Products (3) REST (3) Role (3) SOSL (3) Salesforce Certification (3) Scratch Org (3) Spring 20 (3) Study Notes. (3) Summer15 (3) VS Code (3) Web Technology (3) Winter21 (3) automation tool (3) configuration (3) dynamic apex (3) license (3) mapbox (3) singleton (3) version controlling (3) AppExchange (2) Asynchronous Apex (2) Asynchronous callout (2) Aura Framework (2) Bulkify (2) Community (2) Data Architecture and Management Certification (2) Devops (2) Distributed Version Controlling (2) ES6 (2) Eclipse (2) Einstein (2) Enhancement (2) Enterprise Territory Management (2) Financial Services Cloud (2) Force.com IDE (2) Governor Limit (2) Groups (2) IBM (2) Implicit Sharing (2) JourneyToCTA (2) LWC (2) Lightning Design System (2) Live Agent (2) Metadata (2) PD II (2) Price Book (2) Queueable (2) SFDX (2) Sharing (2) Spring 15 (2) Summer17 (2) Territory (2) Virtual Event (2) ant (2) basic (2) chatter (2) code coverage (2) coding (2) communication (2) console (2) controller (2) documentation (2) dreamforce (2) git (2) jquery (2) logging (2) object (2) permission (2) process builder (2) salesforce1 (2) strategy (2) visual workflow (2) xml (2) Action Plan (1) Action Plan Template (1) Activity Timeline (1) Advanced Currency (1) Agent Productivity (1) Analytics (1) Apex Sharing (1) Arrow (1) Batch (1) Bots (1) Browser (1) Bulk data load (1) CTA (1) Calendar (1) Canon (1) Case Management (1) Celebration (1) Cheat Sheet (1) Classic (1) Compare (1) Confetti (1) Constructor (1) Contact Center (1) Continuation (1) Continuous Integration (1) Convert (1) Cookie (1) CumulusCI (1) Custom Metadata (1) Custom Object (1) Custom Permission (1) Customer (1) Data Model (1) DataCategories (1) DataGrid (1) DataTable (1) Dated Exchange Rate (1) Decorator Design Pattern (1) Dev Hub (1) Development (1) Diwali (1) EDA (1) ESLint (1) Education Cloud (1) Email (1) FSC (1) Function (1) Future (1) Global Gathering (1) Goals (1) Guest Access (1) Guest Profile (1) Guest User Sharing Rule (1) Guide (1) HEDA (1) Higher Education (1) Household (1) Husky (1) IDE (1) Ideas (1) Improvement (1) Invocable (1) KPIs (1) Knowledge (1) Large Data Volume (1) LastModifiedDate (1) Lightning Knowledge (1) Manage Currencies (1) Manual Sharing (1) Metrics (1) Multi Currency (1) New (1) OOPS (1) OWD (1) Omni-Channel (1) Optimize (1) Partner (1) Permission Set (1) Person Account (1) Photo (1) Pipeline (1) Platform Developer I (1) Platform Developer II (1) Presentation (1) Prettier (1) Product Schedule (1) Profile (1) Promise (1) Prototype (1) Public Site (1) Query Plan (1) QuickReference (1) Related records (1) Reports (1) Retrieve (1) Role Hierarchy (1) SAL (1) Salesfor (1) Salesforce Advisor Link (1) Salesforce Labs (1) Salesforce Optimizer (1) SalesforceDx (1) Schedule (1) Session (1) Sharing Rule (1) Sharing Sets (1) Site (1) Skills (1) Snap-ins (1) Spring 17 (1) Summer14 (1) Summer16 (1) Summer19 (1) Switch (1) SystemModStamp (1) Tile (1) Timeline (1) Unauthorized Access (1) User License (1) Users (1) Validation Rule (1) Web (1) Webservice (1) Winter'15 (1) Winter'17 (1) access (1) actionFunction (1) actionPoller (1) actionRegion (1) actionSupport (1) agile (1) app (1) approval process (1) aura (1) awesome (1) backup (1) bitbucket (1) book (1) campaign (1) change set (1) cli (1) code (1) csv (1) custom button (1) custom settings (1) customization (1) data loader (1) database (1) delegate Admin (1) describe (1) dom (1) duplicate (1) dynamic (1) dynamic form (1) email template (1) email-to-case (1) equals (1) error (1) field-level security (1) folder (1) ftp (1) generic (1) gift (1) global describe (1) hashcode (1) import wizard (1) jenkins (1) keynote (1) long running requests (1) monitoring (1) mysql (1) page layout (1) personal (1) power of one (1) record type (1) relationship (1) request (1) review (1) solution (1) sub-tab (1) survey (1) tab (1) username (1) workflow (1)

Popular Posts

Total Pageviews

Contact Me

Name

Email *

Message *