Salesforce Development Tutorial (LWC): How to use Lightning Web Component’s in List View Buttons

https://youtu.be/oPTQ-Il1eFE

Why Bother Using an LWC in a List View Button?

If you need to create some custom functionality that is accessible to your users via a list view (or potentially a related list), then a list view button is the way to go. The reason that you should prefer to utilize an LWC (despite the fact there is no obvious way to use an LWC for a list view button) is because LWC’s load faster than any other component type and, of the available list view button options, they are the most consistent with Salesforce’s Lightning Experience look and feel.

Unfortunately, while it’s super simple to setup and LWC for a list view button, Salesforce has no documentation on how to do so and virtually no answers exist for how to do this anywhere online, but NO MORE!! Today I’ll show you three different methods of creating an LWC List View button! Two methods do not allow you to send the ids of selected records in a list view and one does. I’ll give you the pros and cons of each and how to setup each one below.

One additional note, all of the below solutions will allow the user to traverse from the list view button back to the exact list view they were previously on without the help of visualforce at all! Something else that was undocumented and challenging to figure out.

DISCLAIMER: As of this writing, LWC quick actions are not usable on list views, this could change in the future however, so make sure to investigate that.


Setting up the Lightning Web Component

In any of the three scenarios we are going to use the same Lightning Web Component to demo the functionality, although in the third scenario (a flow based scenario) we will be making slight modifications to allow for the ids of records to get passed through to the component. Let’s take a look at the core of the component below (or on GitHub here).

HTML File:

<template>
	<lightning-button label="Return to List View" onclick={close}></lightning-button>
</template>

JS File:

import {LightningElement} from 'lwc';

export default class ListViewButton extends LightningElement {

	close(){
		setTimeout(
			function() {
				window.history.back();
			},
			1000
		);
	}
}

XML File:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <description>List View Button</description>
    <isExposed>true</isExposed>
    <masterLabel>List View Button</masterLabel>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__Tab</target>
        <target>lightning__FlowScreen</target>
    </targets>
</LightningComponentBundle>

Alright alright alright, so we have all of the files outlined above, let’s make talk about the close function in the JavaScript file first. I did an ENORMOUS amount of experimentation trying to get a list view button that spawns an LWC to allow me to traverse back to the exact list view that I had previously come from and this was the only way I could consistently get that to happen. I tried navigationmixin and it had trouble remembering where to go no matter what I did, I tried return urls, I tried a ton of junk, but that close function above does the trick every single time (at least in a browser, never tried on a mobile app). It always goes back to the exact list view I was on when I clicked the button.

So what does that function actually do? It basically looks to your browser windows history and moves back one page in time, the set timeout function allows it to take up to one second to make that happen. I would suggest using the set timeout as I had issues using this function without it, occasionally it wouldn’t have enough time to operate and failed. This however is used by thousands of users in my org now with no complaints.

The second thing I wanna go over is the XML File’s targets. For simplicity I just put every target we are going to need when we go through each of the three LWC list view button methods, that being said, you only need to declare the target for the method you choose to use. If you use the App Builder method, use the AppPage target, if you use the Tab method, use the Tab target, etc.


LWC List View Button Method 1: The Lightning App Builder Page Method

WHETHER YOU USE THIS METHOD OR NOT, READ THROUGH IT!! THE VAST MAJORITY OF THE STEPS ARE IDENTICAL FOR ALL OTHER VERSIONS SO THEY WILL ONLY BE SHOWN HERE AND REFERENCED IN THE OTHER SECTIONS!! Admittedly, this is my least favorite method, however it does work and some people may prefer it, so I’m gonna show you how to do it real quick. To use this method we need to create a lightning app builder app page. If you don’t know what that is, check out this trailhead. Once you’ve created the app builder page, you need to drag and drop the LWC (shown in the section above) onto the page. You can find the LWC in the section show below:

After you’ve placed your LWC on the page, save and activate your App Builder page. Then click anywhere in your lightning app page canvas that isn’t specifically your LWC to bring up the page information on the right side of the screen. Grab the “Developer Name” value, you need it for the next step.

Now that an app builder page houses our component, and we have the dev name for the app page, we need to setup a list view button to pop open our page for us. Kewlio Julio, let’s get to it.

Go to the object manager and find the object you are creating a list view button for. On the object page, click the “buttons links and actions” link, then click the “New Button or Link” on the top right of that page.

On the new button or link page, you are gonna fill out the follow:
1) Fill out a Label (this can be whatever you want)
2) Select the “List Button” display type
3) Select the “Display in existing window without sidebar or header” Behavior.
4) Select the “URL” Content Source
5) In the free text area put the following URL: /lightning/n/App_Page_Developer_Name
6) Save your button

To place your new LWC list view button on your objects list view, click on the “Search Layouts for Salesforce Classic” tab on your object and then click the drop down arrow next to the “List View” layout and select the “Edit” value in the drop down.

On the edit page for the list view layout, scroll down to the “Custom Buttons” section and select your new list view button.

Now, if you traverse to your object in the app launcher, you should be able to see your button on any list view and click it. This should result in your LWC popping up for you as shown below!

The Pros and Cons of this approach are the following:
Pros:
1) It’s the second fastest of the three options to load
Cons:
1) You cannot get rid of the app builder title area without janky css hacks
2) The tab method (outlined below) loads considerably faster.
3) This can load in an iframe depending on your settings.
4) Can’t pass in list view selection ids


LWC List View Button Method 2: The Lightning Component Tab Method

This is my absolute favorite method, it loads ultra fast and is the easiest to setup. If you don’t need list view ids passed into your LWC, this is the way to go in my opinion.

This method works much like the first method, the setup is virtually identical aside from the fact that you setup a Lightning Component Tab to use as opposed to a Lightning App Builder App Page. Even the List View button setup is the same, the only difference is that you use the lightning tabs developer name at the end of the URL. So to save my hands some typing I’m only gonna show you the tab setup, please refer to the rest of the steps in the App Builder setup instruction above.

To setup a tab to use instead of an app builder page is simple. In setup go to Tabs. Then on the Tabs screen, scroll down to the “Lightning Component Tabs” and select the “New” button.

On the new lightning component tab screen select your lightning component (the one shown above or the one you’ve built), enter a tab label, a tab name and select a tab style and you’re done. MAKE SURE YOUR LWC HAS A TARGET IN THE XML FOR TABS (this is shown in the code up above), otherwise it won’t be selectable.

Once you’ve created your tab, just follow the exact steps outlined in the app builder app page scenario to for the lightning button setup and you’re done!

Pros and Cons of this approach:
Pros:
1) Fastest load time
2) Easiest setup
3) Never loads in an iFrame
Cons:
1) Cannot load in list view ids from selected list view values


LWC List View Button Method 3: The Flow Screen Method

I will urge you to please not use this method unless you absolutely need the selected list view ids passed into your LWC. I say this because the load times are significantly slower and now you have to involve two technologies (flow and lwc) instead of one, making it more complex to deal with, albeit not by a ton.

The steps for setting up the actual list view button for this method are virtually identical to others as well, aside from the URL structure for the list view button, which we will cover, but refer to the first method for setting up the majority of the actual button.

Alrightyyyyy then, here we go. This final method utilizes a flow to allow us to capture the incoming selected list view ids and send them to our LWC to manipulate.

The first thing we need to do is update our LWC a bit to allow it to receive these incoming list view ids, so let’s do thattttttt. I’ll post the code below and then discuss it.

HTML:

<template>
	<p>These are the list view ids passed: {listViewIds}</p>
	<lightning-button label="Return to List View" onclick={close}></lightning-button>
</template>

JS:

import {LightningElement, api} from 'lwc';

export default class ListViewButton extends LightningElement {
	@api listViewIds;

	close(){
		setTimeout(
			function() {
				window.history.back();
			},
			1000
		);
	}
}

XML:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>51.0</apiVersion>
    <description>List View Button</description>
    <isExposed>true</isExposed>
    <masterLabel>List View Button</masterLabel>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__Tab</target>
        <target>lightning__FlowScreen</target>
        <target>lightning__RecordAction</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__FlowScreen">
            <property name="listViewIds" type="String[]"></property>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

First let’s talk about the JavaScript file. We added two things to that file, the first is that we are now importing api at the top so that we can use the api decorator. The second is that we have created the listViewIds variable with the @api decorator on it. This allows the variable to be written to by the flow.

Next let’s talk about the metadata file, in the metadata file we have added a targetConfig. This target config allows us in the flow builder to declaratively assign the incoming list view ids to the LWC’s listViewIds variable.

Last, in the HTML file we have just created a paragraph tag to view the list view ids when they are brought over.

Now that we’ve updated the component, we need to create the flow. In setup, go to Flows and then select “New Flow” at the top to create a new flow.

You will immediately be presented with options for the type of flow you’d like to create, select “Screen Flow” and press the “Next” button., then select the “Freeform” option. You will then land on the flow builder canvas.

The first thing we need to do is create a variable. In the “Toolbox” area on the left side of the screen click the “Manager” tab and then click the “New Resource” button.

After clicking the “New Resource” button a modal will pop-up. Do the following:
1) For Resource Type select “Variable”
2) Fill out the API Name field with the value “ids” (do not include the surrounding quotes). IT MUST BE THIS VALUE TO WORK!
3) For “Data Type” select “Text”
4) Check the, “Allow Multiple Values (Collection)” checkbox
5) Check the, “Available for input” checkbox
6) Click the “Done” button


After setting up this variable you’ll need to grab a screen flow from the “Elements” tab in the toolbox and drag it onto the flow canvas.

On the Screen element modal that pops up you’ll want to do the following:
1) Enter a label and API Name
2) Uncheck the “Show Header” checkbox
3) Uncheck the “Show Footer” checkbox
4) On the left side of the modal in the “Components” area select your LWC and drop it on the page
5) Fill out the API Name for your component
6) place the “ids” variable we created above in the “listViewIds” box for the LWC
7) Click the “Done” button

Then connect your start node to your new screen node, grab the API name of your flow from the settings area of the flow canvas, activate your flow and you’re done!

The one and ONLY step that changes for the list view button setup for the flow variety is the url structure. The URL structure should be changed to the following: /flow/Flow_Developer_Name

Aside from the above, all of the other steps are the same, so please reference the first LWC Button setup method above for more info.

Pros and Cons of this method:
Pros:
1) This is the only method that can receive the ids of values selected in a list view

Cons:
1) This is by far the slowest loading method
2) It forces you to use a flow to embed your LWC
3) It’s the most complex setup
4) It hosts itself in an iFrame

Alright, that’s all folks, this blog post was long and my hands are tired. Hasta Luego!!!!!


Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!


Check Out More Coding With The Force Stuff!

If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps

Good Non-SF Specific Development Books:

Clean Code
Clean Architecture

Salesforce Development Tutorial (LWC): How to use Data Attributes to easily pass data from your component HTML template to your JavaScript Controller

What are Data Attributes and Why Should I Use Them?

Data attributes are a truly magical thing that will, at some point, get you out of some prickly situations as a front end developer. They are essentially a way of storing data on an html element so that when a JS event gets fired your JS controller can easily get access to the data on the HTML element that fired the event.

This is especially useful in scenarios where you want to use for:each templates to generate tables, tabs or whatever else on the screen.


How to use Data Attributes (Example Code and Explanation)

Using data attributes is easy peasy lemonnnnnnnnnnn squezzyyyyyyyy… I’m sorry, it just felt right. Seriously though, it’s easy. Let’s first take a look at how we setup our HTML Template to use data attributes on a button element.

<template>
<lightning-button onclick={getDataAttributes} label="Click Me Bruh" data-donkey="donkeysAreKewl" data-turtle="NinjaTurtles"></lightning-button>
</template>

You see those weird attributes on my element? The “data-donkey” and “data-turtle” attributes? Those are data attributes and as you can see they can be named anything! However they must be in this format: data-randomnameyouchoose. Anything can come after the “data-” when setting up the data attributes on your element (do make sure each attribute has a unique name though!). Pretty cool right? The best part comes next though! Let’s check out the JavaScript Controller’s getDataAttributes method.

import {LightningElement} from 'lwc';

export default class LwcDataAttributes extends LightningElement {
	getDataAttributes(event){
		console.log('This is the data set ::: ' + 
                JSON.stringify(event.target.dataset));
		console.log('This is the data set turtle ::: ' + 
                JSON.stringify(event.target.dataset.turtle));
	}
}

You see that console log that has the “event.target.dataset” value in it? That event.target.dataset produces a Map that houses all of your data attributes in it. The output looks like this:

{"donkey":"donkeysAreKewl","turtle":"NinjaTurtles"}

As you can see it’s a key value pair, the key is whatever you named your data attribute on the HTML Element (notice the data- is excluded however) and the value is whatever value you assigned to that element on your HTML Element.

Now, you may also noticed in the console log below that one that we have the “event.target.dataset.turtle”, this line directly accesses the “data-turtle” value so it will just output “NinjaTurtles”. Pretty niftyyyyy! If you used event.target.dataset.donkey you would get the “donkeysAreKewl” value.

And to be honest that’s really all there is to it, there is one other quick thing we should review though.


What is an Event and the Difference between event.target and event.currentTarget

Boy oh boy does this really confuse people, so let me break it down right quick. Whatever element has the JS event attached to it is the one sending the event parameter to your JS method when you trigger the event (for instance when you use an onclick JS event on an HTML element and then click it to invoke the JS method). THIS IS IMPORTANT! I say this because, it is… trust me, but more importantly you can get into some tricky situations with event.target and event.currentTarget.

The key difference here is that event.target is the TRUE TARGET OF YOUR CLICK! and event.currentTarget is the ELEMENT THAT FIRED THE JS EVENT!

Even if you’ve never done it, you can sometimes wrap multiple elements within a div, and that div is actually the one that houses the onclick event. If you click a button within that div, the button is the “event.target” and the div is the “event.currentTarget”. Be wary of this! If you start to see null values or values you don’t expect in your dataset in your JS controller, this is more than likely why! It has confused many a person (including myself), so just make sure you are paying close attention to which target you are using in your controller.


Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!


Check Out More Coding With The Force Stuff!

If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps

Good Non-SF Specific Development Books:

Clean Code
Clean Architecture

Salesforce Development Tutorial: How to use Named Credentials to simplify your Apex Salesforce Integrations

Why should you bother using Named Credentials?

In short, it’s gonna save you a bunch of time, code and unnecessary configuration, especially when you are authenticating using OAuth. Named credentials basically simplify the authentication portion of your callouts to to external services and allow you do it declaratively through configuration. No matter how hardcode a dev you are, they are 100% worth your time and effort to learn how to use. I promise.


How do you setup a named credential?

You traverse to Setup -> Named Credentials to setup the named credential of your choosing. Named Credentials allow you to authenticate via the vast majority of the authentication methods used by external service providers. You will likely even be able to connect to your internal data bases via named credentials as well if you need to. I’m not gonna go over them all individually in this article. In the video above I got over three different Named credential types and how to configure them. If you’re interested in that portion, please check it out!


How do we reference named credentials in the code?

This literally could not be easier. In fact it’s so simple I think it confuses the hell out of some people, lol. I will give you a simple example below that connects to GitHub via OAuth:

public class GithubOAuthCallout {
    
    public static void callGitHub(){
    	HttpRequest req = new HttpRequest();
        req.setEndpoint('callout:GitHub_OAuth/users/Coding-With-The-Force/repos');
        req.setMethod('GET');
        req.setHeader('Accept', 'application/json');
        req.setHeader('Content-Type', 'application/json');
        Http http = new Http();
        HTTPResponse res = http.send(req);
        System.debug(res.getBody());
    }
}

There are a couple of important things to point out in the code above:

1) When we are setting the endpoint for the HttpRequest we are add the value ‘callout:GitHub_OAuth’ this is how we reference our Named Credential. When you are setting your endpoints for your HttpRequests you pass in your Named Credential by using the following format: callout:[The name of your named credential].

2) If you’ve ever requested data using OAuth authentication you know that we seem to be missing a few steps… We’re not calling out to any authorization endpoints or getting an access token anywhere in the above code. We’re also not setting an authorization header parameter. THAT’S BECAUSE SALESFORCE DOES IT ALL FOR YOU AUTOMATICALLY! Yes… you read that right, automatically, no need to write that code yourself. That ‘callout:GitHub_OAuth’ is doing a ton of behind the scenes magic. It gets that OAuth token for you and automatically sets the authorization header parameter with that token. So wyld right?

Hopefully just that simple example above makes you think twice about choosing to not use named credentials… and if it doesn’t, you probably haven’t done many integrations with external systems yet and don’t realize how much time this saves. IT SAVES A TON OF TIME, CONFIGURATION AND CODE! Trust me on this one. I promise I’m not selling you garbage here. It’s worth using 100% of the time.


Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!


Check Out More Coding With The Force Stuff!

If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps

Good Non-SF Specific Development Books:

Clean Code
Clean Architecture

Salesforce Development Tutorial (LWC): How to create Custom Lightning Web Component Utility Modules

Why create Utility Modules for Lightning Web Components?

If you’re asking this question, I have feeling you don’t often utilize utility modules (or utility classes) anywhere… so let me be the first to welcome you to this absolutely magical world of utilities. They will make your life easier, code updates simpler and your code base a lot less terrifying.

Utility modules are useful in LWC’s because they allow you to take code you commonly use (or may commonly use) between components and allow tons of different components to use that same code without re-writing it a bunch.

Here’s a simple example. Say you pull URL parameters in several different lightning web components and in all of those components you have the exact same method that parses the url and returns those parameters. Instead of adding that method to every single component and having to update that method any time your process for parsing URL parameters change, you could just make a javascript utility module to deal with it, import it into your components and just call that single javascript utility module everywhere you needed to parse URL parameters. In the end this greatly reduces your codebase and the difficulty updating your code in the future.

Maybe the above is still confusing, no worries, let’s check out an example that will hopefully clear any confusion up.


How to create a Utility Module

So to give you a little background on what we’re about to do, I would suggest a little light reading on ES6 Javascript Modules. This will give you a bit better understanding on how all this code I’m about to show you works. If you’re not as obsessive of a reader as me, don’t worry though, I’ll explain everything just a bit throughout the rest of this post.

The first thing we need to do is create an LWC and delete the html file that comes with it as well as all the pre-built code in the javascript file. You might be like wutttttttt??????? But no worries, with utility modules you won’t need them. I know it feels weird right now, but just trust ya boi for one sec.

Next let’s take a look at a very simple LWC module with some exports in it. The name of the below LWC is “util_module”. Knowing the below components name will be important in the near future (GitHub where this code is also available).

//DISCLAIMER: There are many different ways available in ES6 JS to export variables, functions and classes
//you can find out more about exports here: https://developer.mozilla.org/en-US/docs/web/javascript/reference/statements/export

//How to export a variable and make it available when importing your module
//in other components
export const OPEN_STATUS = 'Open';

//How to export a method and make it available when importing your module
//in other components
export function showError(error) {
    return 'This is an error ' + error;
}

//How to export a class and make it available when importing your module
//in other components
export class util_class {

    newStatus = 'New';

    showConsoleLog(){
        console.log('This is the console log ::: ');
    }

}

So what is all that junk up there? It’s not all that complicated after you get familiar with it. Basically what you are seeing are a handful of ways to make things accessible in a javascript module. The key thing here is that “export” keyword. Placing the export keyword in front of a variable, function or a class will allow you to import them into other components. Which brings us to the next part of this lesson, “How tf do we use this utility module”. Let’s check that out.


How to Import/Use your LWC Utility Module

Alright my guys (and gals), let’s check out the code to import that adorable little utility class we made up there into one of our normal LWC’s .

import { LightningElement } from 'lwc';

//Importing in our javascript utility module. The import variable names (OPEN_STATUS, //showError, util_class)
//are the names of the exported variable, method and class in our util_module component
import { OPEN_STATUS, showError, util_class} from 'c/util_module';

export default class Demo_component extends LightningElement 
{
    openStatus;
    returnedError;
    newStatus;

    //The connectedCallback method runs on component load
    connectedCallback()
    {
        //assigning our imported OPEN_STATUS value to our local openStatus variable
        this.openStatus = OPEN_STATUS;

        //assigning our imported showError methods return value to our local returnedError 
        //variable 
        this.returnedError = showError('Tacos had an error');

        //assigning our imported class's newStatus variable to our local newStatus variable
        this.newStatus = new util_class().newStatus;

        //Calling our imported class's showConsoleLog method
        new util_class().showConsoleLog();
    }
}

You’re thinking one of two things right now. It’s either, “Whoa my guy, it’s really that easy?” or, “Idk wtf that mess means”. For the group in latter, let me help you get into the former group with a little bit of an explanation.

Near the top of our LWC you’ll notice this line:

import { OPEN_STATUS, showError, util_class} from 'c/util_module';

This statement is importing the this various things we marked with the “export” keyword in the util_module LWC we created above. You will notice that the OPEN_STATUS, showError and util_class all are the exact names of the things with the “export” statement next to them in the util_module LWC.

These OPEN_STATUS, showError and util_class imports now become accessible in your class via those keywords. So for instance when we do this assignment:

this.openStatus = OPEN_STATUS;

We are literally assigning the OPEN_STATUS variable value from our util_module LWC to our local openStatus variable. Pretty cool right? Hopefully this makes things a little clearer… maybe… If I’m lucky anyway.

And that’s really it everyone! If you have any questions feel free to ask. I typically respond pretty quick.


Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!


Check Out More Coding With The Force Stuff!

If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps

Good Non-SF Specific Development Books:

Clean Code
Clean Architecture

Salesforce Development Tutorial: How to Setup Visual Studio Code for Salesforce Development

Why use an IDE?

First things first… after you use an IDE you will never ask this question again. IT MAKES YOUR LIFE SO MUCH EASIER! Please take the time to leverage an IDE when doing development. Your work will take a fraction of the time it would take otherwise.

Ever wish your code editor would auto-complete method names, field names, object names, etc for you? Well an IDE will do that along with tons of other things that will simply development.

As for why you would pick Visual Studio Code specifically for Salesforce Development, you would do that because it’s an excellent IDE and it’s the only IDE with plugins that Salesforce itself maintains. That’s right, THE ONLY ONE! There are two other big contenders, the Illuminated Cloud 2 for IntelliJ and The Welkins Suite, but the Salesforce Extension pack for VSCode is the only one upkept directly by Salesforce. As such, it has a large team of developers constantly working to keep it up to date and as useful as possible for your work as a developer on the platform.

How do we setup Visual Studio Code for Salesforce Development?

It’s not super complicated, but can be confusing your first handful of times setting things up. Before I get started, if you’d rather read my GitHub wiki on the subject you can find it here.

You first need to install a handful of things if you haven’t already:

1) Install VSCode
2) Install the Salesforce CLI
3) Optionally install Node.js and npm (there are a lot of great packages in existence you can leverage, but we’re not gonna over those here, just know it can come in handy down the line)

After you have installed VSCode and the Salesforce CLI, you then need to open VSCode, click on the extensions icon and search for the Salesforce Extension Pack. After you find the extension pack, install it.

How to Setup a Project (Using the org based development model)

Before I get into this, if you’re not sure what an org based development model is, it basically means your source of truth for your codebase is still your production org instead of a repository. In a later tutorial I will go over how to actually leverage SFDX and a repo based model, but I want to ease people into this and I know from being involved in twenty three different orgs now, the majority of clients are still stuck in the org based model… so we’re gonna start here.

There is one VERY IMPORTANT HOT KEY YOU NEED TO REMEMBER IN VSCODE and that hotkey is the one that brings up the command palette Ctrl+Shift+P. Remember it, love it, appreciate it, don’t forget it (or do and just come back to this article to remember it).

Alright, now that those things are out of the way, let’s go through the steps to setup our project:

1) Bring up the command palette and run the SFDX: Create Project with Manifest command (technically creating it with a manifest is optional these days, but you’ll see why it’s still beneficial later).

2) When prompted, choose the standard template for your manifest file (unless you would prefer an empty or analytics based template). The standard template creates an xml file that would pull all your code from the org.

3) After your SFDX project has been created it’s in your best interest to find the sfdx-project.json file, open it and update the sfdcLoginUrl to have the login URL for your org. Some orgs have MyDomains they have to login through. It’s super useful for those scenarios.

4) After you update the sfdx-project.json, pull up the command palette again and enter the command SFDX: Authorize an Org. This command will ask you what URL you would like to use to connect to your SF org, ask you to enter an alias for your org (this can be anything) and eventually bring up a browser window and allow you to authenticate/login to your org you want to connect to.

5) That’s it, your project is setup! But now how to do we pull in the metadata from our org into our local project? Still super simple, but the next section covers it.

How to retrieve metadata from your org

There are actually two ways to do this, one leverages the manifest file we created earlier when setting up our project and the other uses the org browser. Let’s check out both methods.

Retrieving Metadata from the Org Browser

To the left of your Visual Studio Code workspace, after successfully setting up your project and connecting to your org, you should see a cloud icon. If you click that cloud icon you will bring up the org browser. This allows you to bring up all the metadata in your org. If you hover over a metadata item, to the right of it you will see an icon shaped like a cloud with an arrow. Clicking this icon will allow you to pull the metadata into your local project.

Retrieving Metadata using the manifest package.xml file

Before we get into this, there is an extension called “Salesforce Package.xml Generator” that will make setting up these package.xml files way easier.

This method is very useful if you intend to pull a ton of specific data from your org into your projects consistently. It’s also quite a bit faster than the org browser is in those situations.

To use this method to pull in metadata, do the following:

1) You should see a “manifest” folder in your project. Inside that folder there should be a file called “package.xml”. You can either leave it alone or update the package.xml file to include more metadata types to pull from your org. When you retrieve data in the next step, you will only retrieve data types declared in your package.xml file. For more information please check out the supplementary links section of this wiki article

2) In the command palette run the SFDX: Retrieve Source in Manifest from Org command. This should pull in all the metadata from your org that you outlined in your package.xml file.

Other Useful Things To Setup

The above stuff is the only stuff that’s required to get up and running, but the stuff I outline below will make your life suck way less.

How to get auto-complete to work for object fields

1) In the command palette run the SFDX: Refresh SObject Definitions command so that you can get autocompletion on your object fields.

If you want your SObject definitions to automatically refresh every time you open your VSCode project, do the following:

In the extension settings under “Salesforce Apex Configuration” there is a checkbox for “Enable-sobject-refresh-on-startup”. This automatically refreshes your sobjects from your org when your project is loaded.

How to Auto-Deploy to your org on save

If you didn’t know, by default you won’t auto-deploy to your org when you save your code. You have to right click on your file in the project and select the option that deploys the code to your org. If you want auto-deploy to be setup, follow these steps:

1) In VSCode go to File -> Preferences -> Settings.
2) Click the Extensions drop down
3) Click the Salesforce Feature Previews extension
4) Check the box next to “Push-or-deploy-on-save”
5) It’s also in your best interest to enable the “Detect Conflicts At Sync” feature preview in settings if you use the auto-deploy on save feature. By enabling this you will be informed if your save has any conflicts with other developers code before you actually deploy it to your org.

Still want more info?

In the GitHub wiki article I have even more useful stuff and I update it frequently. Check it out!


Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!


Check Out More Coding With The Force Stuff!

If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps

Salesforce Development (LWC): How to Communicate between Aura Components and Lightning Web Components Using Custom Events and the Api Decorator

Why Would You Want to Communicate Between Component Types?

There are a bunch of reasons it’s beneficial to communicate between component types but the most common ones that I have found are the following:

1) You’re building a new component and realize you need functionality that only Aura Components support, but it’s a very small piece of the component. Instead of building the entire thing in an outdated and much less performant Aura Component, you build most of it in an LWC and just communicate to a small Aura component to do the function only it can do.

2) You’re staffed in an Aura heavy org and when you start building new things for the existing Aura components you should build them in LWC. You can easily do this, but you need to know how the communication channels work between component types.

Once you see how easy it is to communicate between components it’ll be much easier to switch to LWC’s to do development for everything moving forward.


How to Communicate from an LWC to an Aura Component

This is super simple but it’s confusing if you’ve never done it before. We’re basically just gonna create a custom event in our LWC and handle that event in the Aura Component. Let’s check out the code and then I’ll explain it a bit:

<!--This is the LWC HTML-->
<template>
    <lightning-input class="dataToSend" placeholder="Enter text to transfer">
    </lightning-input>
    <lightning-button variant="brand" label="Pass data to Aura Component" 
    onclick={communicateToAura} ></lightning-button>
</template>
//This is the LWC JS Controller
import {LightningElement} from 'lwc';

export default class LwcCommunication extends LightningElement
{
    //This method creates a custom event that dispatches itself.
    //The Aura component then handles this event
    communicateToAura()
    {
         console.log('Communicating to Aura ::: ');

         //We are grabbing the value from the lightning input field that has the dataToSend 
         //class
         let dataToSend = this.template.querySelector(".dataToSend").value;

        //We are creating a custom event named senddata and passing a value in the detail 
        //portion of the custom event
        const sendDataEvent = new CustomEvent('senddata', {
            detail: {dataToSend}
        });

        //Actually dispatching the event that we created above.
        this.dispatchEvent(sendDataEvent);
    }
}
<!--This is the Aura Component HTML-->
<aura:component description="Aura_Communication">
	<aura:attribute name="dataReceived" type="String"/>

	<!--The onsenddata is what handles the custom event we made in our LWC-->
	<c:lwc_Communication onsenddata="{!c.receiveLWCData}" aura:id="lwcComp" />
        <p>This is the data receieved from our LWC: {!v.dataReceived}</p>
</aura:component>
({
       //This is the Aura JS Controller
	
        //This method receives data from our LWC and sets the dataReceived
	//Aura attribute with the events dataToSend parameter (this is the name of the 
        //variable we send in the LWC)
	receiveLWCData : function(component, event, helper)
	{
	    component.set("v.dataReceived", event.getParam("dataToSend"));
	}
});

Alright so now that you’ve checked out the code let’s go over this just a lil bit. In the communicateToAura method above you can see that we create a CustomEvent object and we give it the name ‘senddata’, we also pass some data in the custom event by using the detail property of our Javascript custom event object.

Then in the Aura component’s html we can see that we import our lightning web component using this line:

<c:lwc_Communication onsenddata="{!c.receiveLWCData}" aura:id="lwcComp" />

You can see that when we import our lightning web component that we have an onsenddata event that calls a method in the Aura Components javascript controller called receiveLWCData. When you dispatch your senddata event in your lightning web component the Aura component handles it with the onsenddata event attached to the lightning web component.

Finally you can see that we get the data from the event that was passed to us in the receieveLWCData in the Aura Components JS controller. The most important part of the method is the event.getParam(“dataToSend”). You are grabbing the variable that you passed into the detail property of your CustomEvent object in your LWC. Let me put them side by side so you see exactly what I mean:

//LWC Custom Event code
const sendDataEvent = new CustomEvent('senddata', {
            detail: {dataToSend}
});

//Aura code
component.set("v.dataReceived", event.getParam("dataToSend"));

And believe it or not it’s really that simple. You have successfully passed data from your LWC to your Aura component. Now let’s figure out how to do this in reverse.


How to Communicate from an Aura Component to an LWC

Alright so how do we do the exact opposite of what we did above?? It’s pretty simple but we need to leverage the wonderful @api decorator for lightning web components to make this work as opposed to Aura event communication. Alright so let’s check out the code below and then I’ll go over it a bit more in detail:

<!--This is the LWC Template/HTML-->
<template>
	<p>This is the data received from the Aura Component: {dataReceived}</p>
</template>
//This is the LWC JS Controller
import {LightningElement, api, track} from 'lwc';

export default class LwcCommunication extends LightningElement
{
	//Tracked variables ensure that they are refreshed on the page when their values are
	//updated in the code
	@track dataReceived;

	//The api decorator makes this a public method that any component that houses this 
        //component can access/call
	@api receiveData(data)
	{
	    this.dataReceived = data;
	}
}
<!--Aura Component HTML-->
<aura:component description="Aura_Communication">

	<!--The onsenddata is what handles the custom event we made in our LWC-->
	<c:lwc_Communication aura:id="lwcComp" />

	<lightning:input aura:id="dataToPass" />

	<lightning:button label="Pass data to LWC" onclick="{!c.passDataToLWC}"/>
</aura:component>
({
        //This is the Aura Component JS Controller

	//This method sends out data to our LWC from the Aura component.
	passDataToLWC : function(component, event, helper)
	{
		let stringToSend = component.find("dataToPass").get("v.value");

		//We are calling the receieveData method in our Lightning Web Component here
		component.find("lwcComp").receiveData(stringToSend);
	}
});

Alright, so as you can see nothing super complicated just some weird stuff you may not be super comfortable with yet. There are two very important pieces to making the passage of data between components possible.

The first is the @api method in the LWC. The receiveData method has the @api decorator in front of it. This makes the method public available to its parent component regardless of what component type it is.

The second is the component.find(“lwcComp”).receiveData(stringToSend) line in the passDataToLWC method in the Aura Components Javascript controller. This is finding the lwc that we imported into our Aura Component by its aura:id and then calling the receiveData method in the LWC (the method with the @api decorator) and passing it data.

This is surprisingly simple thankfully, no weird hacky tricks necessary just a few lines of code and we’re all good to go! If any of this is super confusing please check out the video above. I go over every aspect of the code in great detail.


Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!


Check Out More Coding With The Force Stuff!

If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps

Salesforce Development: How to Setup Illuminated Cloud 2 with the IntelliJ IDE

What is an IDE?

IDE stands for Integrated Development Environment. Its primary purpose is to make your life as a developer considerably easier by doing things like:

1) Syntax Highlighting
2) Auto-completing functions names, field names, object names, etc.
3) Integrating git easily
4) Improving debugging functionality
5) Putting your command line in the same place you develop.
6) Tons and tons of other things

It is well worth your time to invest an hour or two to figure out how to use an IDE to improve your productivity as a developer.

More info on the IntelliJ IDE here


The Salesforce IDE’s

Back when I started developing on this platform the only IDE’s we had was the Force.com IDE in Eclipse and the Dev Console… if you really count it. Today there are five IDE’s to choose from and I’m gonna walk you through how to install and configure my personal favorite, Illuminated Cloud 2.

Before I get started here are a list of your IDE options and their prices:

1) IntelliJ (Illuminated Cloud 2) – $90 a year
2) Visual Studio Code (SF Plugins) – Free
3) Welkins Suite (Pure SF IDE) – $150 a year
4) Eclipse (Retired Force.com IDE) – Free
5) Dev Console – Free


I struck out the last two because you really shouldn’t ever use them even though they are technically available options.

I have tried out all of them and my preference is IntelliJ/Illuminated Cloud 2 and that’s because between the incredible power of the widely used and extremely popular IntelliJ IDE and the impeccable work Scott Wells has put into Illuminated Cloud 2 to help it leverage all of those IntelliJ features for SF development, it’s borderline impossible to top it. It is the most point and click/easy to use of them all and it does not suffer because of it.


How to Setup IntelliJ and Illuminated Cloud 2

Here are the steps necessary to setup and be able to use Illuminated Cloud 2 for Salesforce development in IntelliJ.

1) Install the most recent JDK

2) Install the most recent version of IntelliJ Community Edition (or Ultimate if you want to pay for the advanced features)

3) After the JDK and IntelliJ have been installed, open IntelliJ and go to File -> Settings -> Plugins, click the Marketplace tab at the top and search for Illuminated Cloud

Illuminated Cloud 2 Plugin IntelliJ

4) Click the install button to install Illuminated Cloud 2 (Do not install the original Illuminated Cloud option, it is outdated).

5) After Illuminated Cloud is done installing and IntelliJ restarts, start creating a new IntelliJ project. File -> New -> Project -> Illuminated Cloud.

IlluminatedCloudProject

6) Click the “New Connection” button in the top right (the pencil icon). It will pop-up a new Connections modal. In that new modal click the “Create Connection” icon in the top left (the plug icon).
IlluminatedCloudConnections

7) Enter the information it requests: Organization type, username, password, security token (if you don’t know what the security token is my video above explains where to find it in SF) and then click the “OK” button in the bottom right.

8) If you entered in the right connection information it will give you a confirmation message that your information was valid and it will connect to your org and give you a preview of the metadata you can pull from your org.
IlluminatedCloudMetadataPreview

9) Check the checkboxes next to the metadata you would like to pull for your org and then hit the next button.

10) After hitting the next button, name your project and module whatever you’d like to name them and then click the “Finish” button!

11) That’s it you did it! You can do SF dev work in IntelliJ!


Useful Illuminated Cloud 2/IntelliJ Hotkeys

There are a ton of useful hotkeys for both IntelliJ and Illuminated Cloud 2. You can find all the Illuminated Cloud 2 hotkeys here and all of the IntelliJ hotkeys here.

Here is my shortened list of hotkeys I use every single day:

1) Reformat Code: Crtl + Shift + L
2) Get more information about a method, object, field, etc: Ctrl + Q
3) Search your entire project: Ctrl + Shift + F
4) Go to external SF Documentation: Shift + F1
5) Go to highlighted Apex Class: Ctrl + N
6) Go to highlighted component: Ctrl + Shift + N

There are tons and tons more that are super useful, so be sure to check them all out!


Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!


Check Out More Coding With The Force Stuff!

If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps

Salesforce Development: Creating a Self-Scheduling Apex Class

Why This Is Useful

Have you ever wondered, “How do I effectively schedule an apex class to run every single minute of the day?” or maybe every hour or second (please don’t schedule anything every second, lol). Well there’s a great way to do it, by having your scheduled apex class reschedule itself! This method also significantly cuts down on the jobs you have to cancel to actually make any updates to your scheduled class as well. Say for instance you did schedule the class to run once a minute. That equates to 1440 scheduled jobs!! That’s a nightmare… with this method, you’ll only have one scheduled job but it will still run every minute of the day. Yay!

So let’s just get down to it… how does this magic work? It’s actually pretty simple. In your scheduled class you just find your currently running scheduled job, abort it and then reschedule it! Let’s check out the code below or on Github.


The Code

/**
 * @description An example of a continually rescheduling job.
 * @author Matt Gerry
 * @date 9/5/2020
 */

public with sharing class Repeating_Scheduler_Example implements Schedulable
{
	private final String JOB_NAME = 'Repeating Job';
	private final Integer ONE_MINUTE = 1;

	/**
    * @description The execute method fires each time the scheduler is run. Unless there is a
     constructor, this is always the first method to fire.
    * @param cont Schedulable context instantiated by the Schedulable implementation
    * @example System.schedule(JOB_NAME, cronExpression, new Repeating_Scheduler_Example());
    */
	public void execute(SchedulableContext cont)
	{
		new Repeating_Scheduler_Case_Insert().insertCase();
		findAndAbortJob(cont);
	}

	/**
	* @description Aborts the existing scheduled job. Then calls rescheduleJob to 
          reschedule this job.
	* @param cont Schedulable context instantiated by the Schedulable implementation
	* @example finaAndAbortJob(cont);
	*/
	private void findAndAbortJob(SchedulableContext cont)
	{
		if (cont == null)
		{
			return;
		}

		//Need to query CronJobDetail to find our currently active scheduled job
		List<CronJobDetail> cronDetail = [SELECT Id FROM CronJobDetail WHERE Name= 
                :JOB_NAME LIMIT 1];

		if (cronDetail.isEmpty())
		{
			return;
		}

		//Need to find the corresponding cron trigger to be able to abort the 
                //scheduled job
		List<CronTrigger> cronTriggers = [SELECT Id FROM CronTrigger WHERE 
                CronJobDetailId = :cronDetail[0].Id];

		if(cronTriggers.isEmpty())
		{
			return;
		}

		try
		{
			//Aborts the job current setup for this scheduled class
			System.abortJob(cronTriggers[0].Id);
			rescheduleJob();
		}
		catch (Exception e)
		{
			System.debug('This was the error ::: ' + e.getMessage());
		}
	}

	/**
	* @description Reschedules this job for one minute in the future.
	* @example rescheduleJob();
	*/
	private void rescheduleJob()
	{
		Datetime sysTime = System.now().addMinutes(ONE_MINUTE);
		String cronExpression = '' + sysTime.second() + ' ' + sysTime.minute() + ' ' + 
                sysTime.hour() + ' ' + sysTime.day() + ' ' + sysTime.month() + ' ? ' + 
                sysTime.year();
		System.schedule(JOB_NAME, cronExpression, new Repeating_Scheduler_Example());
	}
}

Aborting The Job

So as you can see from the above code, all we need to do is take the name of the job and query the CronJobDetail object to find the corresponding Cron Job for our scheduled apex and then we query the CronTrigger object to get that id so we can abort our scheduled apex’s next run. After getting the CronTrigger record Id we then utilize the System.abort method to abort our scheduled apex so that we can reschedule it.


Rescheduling The Job

After we abort the job we simply utilize the System.Schedule method to reschedule our class for a time in the future. In this code we just set it to one minute in the future via a variable, but I would suggest utilizing a custom metadata type to do this as it gives you the most flexibility.


Get Coding With The Force Merch!!

We now have a redbubble store setup so you can buy cool Coding With The Force merchandise! Please check it out! Every purchase goes to supporting the blog and YouTube channel.

Get Shirts Here!
Get Cups, Artwork, Coffee Cups, Bags, Masks and more here!


Check Out More Coding With The Force Stuff!


If you liked this post make sure to follow us on all our social media outlets to stay as up to date as possible with everything!

Youtube
Patreon
Github
Facebook
Twitter
Instagram


Salesforce Development Books I Recommend

Advanced Apex Programming
Salesforce Lightning Platform Enterprise Architecture
Mastering Salesforce DevOps