JavaScript variable scoping and Drafts
June 11, 2020 at 8:19 AM by Dr. Drang
An interesting problem came up in the user forum for Drafts yesterday. User trbielec was making new actions by stringing together other actions that had already been written, an admirable attempt to use the DRY principle. But he was getting error messages about duplicate variable names. This is a rare case in which a scripting problem is related to honest-to-goodness computer science rather than just an error in logic.
A simple example that demonstrates the problem can be built from two actions, which you can install from the links:
consists of a single JavaScript step with this code:
javascript:
let a = "Subroutine";
alert("Greetings from the " + a);
Running this will cause an alert to appear.
has two steps. The first is a JavaScript step with similar code,
javascript:
let a = "Caller";
alert("Greetings from the " + a);
and the second step is an
step that calls . When this is run, a “Greetings from the Caller” alert appears as expected,but instead of then seeing the “Greetings from Subroutine” alert, you’ll get an error message saying you can’t create a duplicate variable a
.
The error comes from JavaScript’s variable scoping rules. JavaScript doesn’t allow you to use let
to define a variable twice within the same code block. You might think that because the two let
statements are in separate actions, they are also in separate blocks, but as trbielec learned, that isn’t the case. Drafts treats all the JavaScript code in an action—even if some of that code is there through an step—as one big chunk. So in our example, it’s as if we had written
javascript:
let a = "Subroutine";
alert("Greetings from the " + a);
let a = "Caller";
alert("Greetings from the " + a);
which is clearly illegal.
The solution is pretty simple. Just wrap one (or both) of the two bits of JavaScript in braces:
javascript:
{
let a = "Subroutine";
alert("Greetings from the " + a);
}
The braces define a block, so now the a
in is different from the a
in and there’s no conflict and no error. runs the way you expect, with both alerts appearing in sequence.
I’ve never had a scoping conflict like this in my Drafts actions, and more significantly, Greg Pierce says he’s never seen it arise in the Drafts forums before, so it’s unlikely you will ever put this blog post to practical use. But it was a fun way to divert myself from the work I should be doing.