References: https://help.salesforce.com/s/articleView?id=sf.users_license_types_communities.htm&type=5
Sunday, April 17, 2022
Monday, December 13, 2021
Javascript: Working with Arrays using Asynchronous operations
Let’s say we have a list of names. For each name, we want to make an API call and get some information, and then keep a new list with this collection of information. A typical approach may look like this.
Refactoring to using map
or forEach
is not that straightforward here. The callbacks provided to map
or forEach
(or any of the array-methods) are not awaited, so we have no way of knowing when the full collection of information is done and ready to use. However, there is still a way we can write this in a nice way. Using the Promise.all
method.
Awesome! Now, map
returns a list of promises, and the Promise.all
method takes a list of promises and resolves them in parallel. Not only did the code become much more nice and clean - but we also benefit from the fact that the promises are not resolved sequentially, which speeds up the process and increases performance.
Javascript: sort() and Array destructuring
Take a look at the code below.
At first glance, this looks good. We’re not using let
, and we’re not mutating on the original array using something like push
. But take a look at the console.log
statement. It turns out that the sort
method does not create a copy of the original array. Instead, it both mutates on the original array and returns its own array from the method call.
And there are a handful of old Array-methods that do this. Be careful with push
, shift
, unshift
, pop
, reverse
, splice
, sort
, and fill
. Fortunately, most often we can simply avoid calling these methods at all, to stay out of trouble.
However, there are cases, like using sort
, where we have to use a method that mutates the original array, in lack of better options. Array destructuring to the rescue! Whenever these occasions arise, make sure to manually copy the array first, before performing an operation on it. It’s as simple as this.
That [...grades]
makes the entire difference.
Javascript: Pass arguments as an object
Say we have a function, createUser
, which requires four arguments in order to create a new user (by calling some API).
When looking at the function signature itself, things seem to make pretty good sense. But how about when we call it?
It’s pretty unclear what the arguments mean, right? Especially the last two booleans. I would have to go to the implementation to look it up. Instead, we can wrap the arguments in an object.
Thanks to ES6 object destructuring, we can do this easily by simply adding curly brackets around the arguments. Now, whenever we call createUser
, we pass an object as a single argument with the required values as properties instead.
See how nice that reads out now. We’re no longer in doubt what those booleans mean. There’s another version of this that I’ve seen very often: Passing optional arguments as an options
object. The idea is to pass 1-2 essential arguments and then pass the remaining arguments as an options
object.
Now we need to check if the options
object is set before accessing its values and provide proper fallbacks. On the other hand, calling the createUser
function now looks very clean.
The first two arguments are pretty obvious, and we can now optionally provide options when needed.
Javascript: Guard clauses and avoiding using 'else'
Guard clauses
“In computer programming, a guard is a boolean expression that must evaluate to true if the program execution is to continue in the branch in question. Regardless of which programming language is used, guard code or a guard clause is a check of integrity preconditions used to avoid errors during execution.”
— Wikipedia
Let’s take a look at an example. We have a function, getValidCandidate
, which checks if a candidate is valid, provided a list of members and returns the member if the candidate is valid, or undefined
otherwise.
Look how nested the code is? Ifs wrapping other ifs, nested 3 times. Let’s rewrite this and use guard clauses instead.
Guard clauses prevent the function from continuing what it’s doing and instead returning early if the guarding condition is not met. Naturally, we also know that the end result is the last return of the function.
Skip the ‘else’ part
Whenever you’re about to write else, stop and reconsider what you’re doing and search for an alternative way to express the logic.
Let’s cover a few ways that we can avoid using else. One of them is guard clauses, which we just covered above. Another approach is using default values. Let’s take an example.
Let’s say we have a function, negateOdd, which takes a number and negates it if the number is odd.
The function does what it’s supposed to. But it’s unnecessarily using an else. Let’s refactor it, and instead, use a default value.
We now assign result with a default value, and the variable will only be changed if the condition in the if-statement is met. But let’s do even better. We’re supposed to question the use of let and imperative (altering the state of your program step by step) code. Let’s see if we can make this function even more readable and concise.
There is a version of if-else that is generally accepted. It’s the ternary operator.