With 17,110 points on the IdeaExchange idea, the arrival of the
switch statement in Apex in the Summer’18 release is an exciting addition to the language that should please many developers.
As a language construct,
switch comes in a number of forms in many languages. You might have seen a similar logical construct referred to as
select, or some other things. The mouthful of a technical definition of
switch is a multiway branch logical control flow feature. If you don’t want to spend time parsing that, it’s basically a syntax structure to evaluate a variable against many possible values without having a bunch of repetitive
else if blocks. It can reduce repetitive code and improve clarity and readability of logical code paths.
Switch in Apex
Each implementation of this feature in each language needs to work for that language. Apex is no different — key point here being Apex is not a general purpose programming language. It is a Salesforce domain-specific language solving problems for developers working with the Lightning Platform.
One minor obstacle is that Apex greatly resembles Java, which uses the syntax
switch...case. Because of this resemblance, many developers expect Apex to follow Java syntax and conventions. Only trouble is in Apex the word “case” already represents the class for the Case sObject. Even if the compiler could be made to cope with a keyword of “case” alongside a class called
Case, it isn’t going to help the cause of readability or clear clean code. So although Apex resembles Java in many ways, the
when keyword is preferred (Largely based on feedback from early beta testers in the Trailblazer community group). Here is a basic representation of the syntax with a String variable being compared to String literals:
Those of you who have used a version of
switch statement in the C-family of languages will immediately notice the absence of a
break statement in each
If you really did take notice, good job!
That’s because in Apex there is no fall-through. This means the first logical branch is executed, then no others. In other words, the first executed branch blocks any following branches in the
The last Apex-specific feature I’ll mention is the types that you are allowed to
switch on. Unremarkably, String, Integer and Long can all be compared to a literal value. But there are also sObject identifier and enum comparisons. These bring some new prospects to how a developer might now structure their code, especially in triggers.
Switch on sObject type
Allowing to evaluate when based on sObject type is exciting. Let’s consider a result set from a custom object, where we have queried the
Owner is polymorphic in a custom object, meaning it can be one of two types, either of type
Group. If the owner is a
User, we will send an email to that owner and if a
Group, perhaps we will post to Chatter.
Note the requirement to upcast prop.Owner to sObject.. The reason for this is that Apex sees the Owner field as the current specific type of User or Group. If what you are already being given is the generic SObject type, this would not be necessary.
The Trigger.operationType context variable
Before I talk about
switch and enums, we need to introduce a new trigger context variable. For a long time, there were six boolean methods on the
Trigger class for testing the operation context of your trigger (before/after and insert/update/delete/undelete). These were adequate, but if you wanted to pass the information of the state of this execution, you needed to potentially have a way of passing them all around. This could mean passing around the Trigger class itself or creating your own structure to do so. Either way, there are downsides.
Well, now we’ve done that for you. All seven execution contexts have been wrapped into a single enum typed context variable called
Trigger.operationType . This context variable is of the type
System.TriggerOperation which has the following values:
If you combine this new context variable and the new Apex
switch feature, trigger code becomes much nicer to read and to reason about.
Switch and enum in triggers
Let’s say you have a trigger, and you’ve followed the best practice of one-trigger-per-SObject. You need to implement the following features in your trigger:
- Create related records in the after update and after insert contexts.
- On before insert set some values before creating the record.
- For compliance, you need a sanity check to prevent deletion of certain sensitive data in a before delete context.
First let’s take a stab at this before the new
Trigger.operationType context variable:
This is working logic, but it also takes some effort to reason out what the trigger is doing. Never mind, if I want to pass this all to a helper method, there is no easy way to pass all of the possible context options.
Now let’s see this in action with the new stuff! Let’s even follow best practices and have a trigger handler static method that we call. So to start, we have the trigger itself.
In this bit of code we’re invoking the handler method
handleTrigger and passing context variables, including the new
Trigger.operationType variable. The handler method now knows everything it needs to know about the current trigger context. Let’s look at the structure of that method:
If you ask me, this reads much more cleanly and understandably. I can reason out exactly what bits of code are being executed in each context and understand where the lines of logic go much more easily.
Awesome, but still version 1
Here it’s worth being specific on what you cannot do with
switch in its very first implementation in Apex. In some languages,
switch will allow you to compare to an expression, a variable, or perform pattern matching, either against contents of data structures or against a regex. If I allow myself to muse and dream of what could be amazing in the Apex, imagine all picklist value API names being automatically surfaced as enums in Apex and being able to switch on that. Not only would it make for super nice to write/read code, but it would also create a compile-time check for a valid comparison value!
Can you think of an amazing feature that would make
switch even better? Please head over to IdeaExchange and submit that idea and socialize it.
So many more Apex features in Summer’18
This blog post calls out some of the features that caught my eye about
switch in Apex, but be sure to take a look at the full documentation and release notes. Also, for better context about why it was built the way it was, there is a great video from TrailheaDX’18. And of course, this can work in many other places besides triggers.
There are a load of features coming to Apex in Summer’18, so be sure to read all the release notes and check out the recording of the Developer Preview in the Release Readiness Live webinar. And don’t forget your Summer’18 release highlights badge!
Finally, to go back to the basics, check out the Apex Triggers module on Trailhead.