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 use Custom Settings to Bypass Your Triggers in Production

Why On Earth Would We Ever Build Trigger Bypasses?

This is an excellent question and one I wondered myself… until my team and I had to do a monstrous 50,000,000 record load into Salesforce for a deployment, lol. I was stumped… how on earth could I ever pull this off without taking days or weeks to upload that data. We’re not gonna into all the detail behind that monster data load, but we’ll just say turning off the triggers was a part of it. Then we were faced with the, you can’t turn off the system while we do this data load and I was like, fml, how though? As it turns out there is a way! And a really good and simple way if you leverage Custom Settings.

There are a number of other reasons to do this too. A data team that loads data that’s pre-transformed (doesn’t need to go through the trigger) or an integration that auto-transform the data and doesn’t need to be bogged down by a trigger. There are plenty more beyond these as well, but these are the major ones.

What are Custom Settings?

Custom Settings are much like Custom Metadata in that they are typically used in the same way as a config file in another programming language. That being said they are a bit different. Unlike custom metadata, custom settings allow you to change the values of the data you store based on the user that is currently running the code. So each user in your system can have different values for custom metadata records. Pretty nifty, if I do say so myself.

So How Do We Set This Bypass Up?

This is so simple it’s mind boggling, lol. All you need to do is setup a hierarchy custom setting object by going to Setup -> Custom Settings and then create Checkbox (Boolean) fields for each object you have a trigger for that you may want to bypass.

After you’re done setting that bad boi up. Click the “Manage” button at the top of your custom setting so that you can create records for it. After you do that you’re going to be presented with two different “New” buttons on the screen and it’s not super obvious what either of them do, so let me explain. The top “New” button is to make default values for ALL USERS in your org. This is the Default Organization Level Value. The bottom “New” button allows you to make new records that are only relevant to certain Users or Profiles. The bottom “New” button is what we want to click.

After clicking the bottom “New” button you’ll be presented with option to select a, “Location” which is the most confusing label of all time, lol. This just expects you to choose a User or a Profile which will then allow you to have unique values for Users and Profiles for your custom setting! Pretty Kewllllllll. Select the profile or user you would like to bypass your trigger(s) and select the checkboxes for the triggers they should bypass and then hit “Save”.

That’s it, pretty damn simple. Now on to the equally simple trigger code.


The Trigger Code

You might be thinking, oh no code… I’m sorry if you feel that way because code is the most amazing thing since General Tso’s Chicken. However, if you do, no worries, we need four lines of code… yes that’s it. Now before I show you this code, please note, you should be utilizing a trigger framework for your code and that no logic should live in your triggers… but that’s for another day. This is just a simple example, so lets check it out.

trigger Account_Trigger on Account (before insert)
{
        //Getting the Process_Switches__c custom setting value that is relevant to our running 
        //user
	Process_Switches__c processSwitches 
        Process_Switches__c.getInstance(UserInfo.getProfileId());

        //If the user can bypass the trigger, return and do not continue the trigger.
	if(processSwitches.Account_Process_Bypass__c)
	{
	    return;
	}

        //Call your trigger handler and run trigger logic
}   

Woop, there it is. Pretty simple stuff. If you’re not familiar with Custom Settings and the unique ways to query data from them the whole [Custom Setting Name].getInstance(UserInfo.getProfileId()) might look a little confusing. It’s pretty simple though. It basically gets the custom setting record that is relevant for the running users profile. This makes sure we always get the correct record and only the right people are bypassing the trigger! Pretty kewl huh? And that’s it, yep, that’s really it. Now go enjoy a trigger free world where your data loads go lightning fast.


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 Make Sure Your Process Builders Never Fire Your Apex Triggers

Why Would We Want Our Process Builders to Bypass Our Triggers?

If you didn’t know process builders fire your triggers every single time they make an update to a record or insert a new record. If you have 5 different update actions in your process builders that means you could potentially fire your triggers 5 times in the same process builder execution!! That would absolutely destroy your operation speeds, and if you didn’t know Process Builders are already know to be very poor performance wise (taking up to 40 times longer than flows or triggers to operate). That being said even process builders have their place, especially in admin heavy orgs. So let’s figure out how to make sure they are as performant as they can be.

As a side note: If your process builders rely on your trigger to re-run after they execute… you have a problem and you need to fix it. Process builders should never require a trigger to re-run after it executes.

SUPER IMPORTANT NOTE: Make sure to re-start your triggers at the end of your process builder. If you don’t you could have pretty horrible ramifications with the data loader and with Database all or none transactions. Don’t worry we go over how to restart them in your process builder as well.


Setting Up The Super Simple Apex Code To Make This Work

First things first. If you want the code and config for this , you can grab it here on github.

Now let’s get to it! Unfortunately we have to write a little apex code to make this magic work (or fortunately if you love code like me), but don’t worry! It’s very simple. The first this we’re going to make it a small utility class that allows us to pass in the name of a trigger we’d like to bypass.

//The utility class that allows us to determine which triggers we want to bypass
public with sharing class Util_Trigger_Name_Bypass
{
	//The set of trigger names that we want to bypass in our trigger.
        public static Set<String> bypassedTriggers = new Set<String>();

        //Method that allows us to add a trigger that we want to bypass
	public static void bypassTrigger(String triggerName)
	{
		bypassedTriggers.add(triggerName);
	}

        //Method that allows us to remove a trigger from our bypassed triggers set
	public static void removeBypass(String triggerName)
	{
		bypassedTriggers.remove(triggerName);
	}
}

There is one major thing to note about the code above. We utilize the static keyword to declare our variable (and our methods too). If you are not familiar with the concept of static (or class) variables, you should definitely take the time to investigate them more, but I will briefly explain it here. Static variable persistent for your entire execution context. What this means is that our variable’s value will remain the same in the trigger and the process builder (and anything else after or inbetween). This is critical! If it wasn’t a static variable we wouldn’t be able to achieve this.

Now that we have this nice utility class that allows us to put the names of the triggers we would like to bypass. Let’s write a couple more small apex classes with invocable methods that our process builder can call to add the name(s) of our triggers we would like to bypass while our process builder is running.

//Class that you can call from a process builder that allows you to stop a trigger from executing
public with sharing class Util_PB_Trigger_Stop
{
	//You can find this invocable apex method in your process builder when you look for 
        //the "StopTrigger" label in an apex action.
	//This method adds trigger names to the utility we made that stores trigger names we 
        //would like to bypass.
	@InvocableMethod(Label = 'StopTrigger' Description='Method allows up to bypass 
        triggers')
	public static void stopTriggers(List<String> triggerNames)
	{
            Util_Trigger_Name_Bypass.bypassTrigger(triggerNames[0]);
	}
}
//Class that you can call from a process builder that allows you to start a trigger again
public with sharing class Util_PB_Trigger_Start
{
	//You can find this invocable apex method in your process builder when you look for 
        //the "StartTrigger" label in an apex action.
	//This method removes trigger names from the utility we made that stores trigger names 
        //we would like to bypass.
	@InvocableMethod(Label = 'StartTrigger' Description='Method allows up to restart 
        triggers')
	public static void startTriggers(List<String> triggerNames)
	{
		Util_Trigger_Name_Bypass.removeBypass(triggerNames[0]);
	}
}

As you can see the above apex classes just allow us to add or remove the names of our triggers we want to bypass to our utility class’s bypassedTriggers Set. Noice, very convenient and very simple. The last two things we need to do are update our trigger, so that it looks to our Util_Trigger_Name_Bypass utility class to determine if it should run and create our process builder!. Let’s take a look at the trigger.

//Our Case Trigger. Please use a trigger framework and never put logic in your triggers.
//I created this trigger in this way for demonstration purposes only and to
//simplify this lesson.
trigger Case_Trigger on Case (before update, before insert)
{
	//Looking at our utility class to determine if we should run our trigger logic.
        if(!Util_Trigger_Name_Bypass.bypassedTriggers.contains('Case_Trigger'))
	{
		Case_Trigger_Handler.beforeUpdate(trigger.new);
		Case_Trigger_Handler.beforeInsert(trigger.new);
	}
}

As you can see from the above trigger, before we execute the logic for our trigger we first check to determine whether or not our utility class’s bypassedTriggers set contains the name of our case trigger. If it does, then we do not execute our logic.


Setting Up The Process Builder

You can setup your process builder to bypass your triggers in two different ways. You can have your process builder shut off the trigger before it runs any operations or you can have it shut off the trigger just within the immediate action blocks that actually update or insert records. I would personally suggest you just turn it off for the entire length of the process builder because it’s more performant that way, so that’s what I’m going to show you below. If you would rather do it the other way, the video linked above explains it in detail.

As you can see from the above pictures this is super simple! We just create two nodes, one to stop the trigger at the beginning of the process builder and one to re-start the trigger at the end of the process builder. Both of those nodes have apex actions within their immediate actions that call the StopTrigger and StartTrigger Invocable apex methods respectively and pass it the name of our trigger we want to disable (in our case the Case_Trigger). Then you place any update or insert actions between those two nodes and you’re good to go! No more trigger logic run while your process builders execute! Wooottttttttt!!!!!!!!! Enjoy that massive boost in process time. The only next steps you have are to eliminate your process builders entirely, lol, because they are just garbage.

SUPER IMPORTANT NOTE: Make sure to re-start your triggers at the end of your process builder. If you don’t you could have pretty horrible ramifications with the data loader and with Database all or none transactions.

Moderately Important Note: Make sure you “Evaluate Next Criteria” in the “Specify What Happens After Evaluating This Criteria” node.


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