Let / Const / Set / Global

Pulsar comes with full support for scoped variables exactly as you know them from other languages. This means you can define a variable within a specific scope, mutate it (or create one that is immutable), and read its value.

Similar to dynamically typed languages, variables are not constrained to specific data types, and as such, there are no type definitions when you declare them.

Variable flows don't define a body, and shorthand flow syntax is recommended.

Let

let flow allows you to define a variable within the current scope:

{* Declaring variable *}
{[ let dogName = "Rex" /]}
{{ dogName }} // Rex

Variables declared with let are mutable, meaning you can change their value inside the same scope they were defined at. When you try to re-define a variable that was already defined, an error is thrown.

Const

const flow allows you to define a variable within the current scope:

{* Declaring variable *}
{[ const dogName = "Rex" /]}
{{ dogName }}                 // Rex

Variables declared with const are immutable, meaning you can't change their value inside the same scope they were defined at. When you try to re-define a variable that was already defined, an error is thrown. When you try to mutate this variable, an error is thrown as well.

Set

set flow allows you to modify a variable defined using let flow:

{* Declaring variable *}
{[ let dogName = "Rex" /]}
{{ dogName }}                // Rex

{* Mutating variable *}
{[ set dogName = "T-Rex" /]}
{{ dogName }}                // T-Rex

Only variables declared as mutable (let) can be mutated, otherwise, an error is thrown. Also, set expects variable to be already defined in the current scope, and it can't define new variables.

You can also use shorthand set as you would in other languages:

{* Declaring variable *}
{[ let dogName = "Rex" /]}
{{ dogName }}              // Rex

{* Mutating variable *}
{[ dogName = "T-Rex" /]}   // Note the missing "set"
{{ dogName }}              // T-Rex

Global

Variables defined with global flow are always defined at the top-most scope, regardless of the scope used to execute this definition. This makes them available to any executed code as soon as they are defined:

{[ if true ]}
   {[ global variableInsideBody = "Text" /]}
   {{ variableInsideBody }}            // Properly executes
{[/]}

{{ variableInsideBody }}               // Also properly executes

Variables declared with global are immutable. The purpose behind this flow is to use it for variables that are needed throughout a blueprint, everywhere, and are constants. A good use for global flow are configuration values:

{[ global mySettings = "1.0" /]}
{[ global myOtherSettings = "abcdefgh" /]}

When defined, you can use them anywhere from that point onwards.

Global variables are not the same as in some languages where they are available to all scripts that run. In Pulsar, globals are only available within a specific blueprint that defined them. If you want to define variables that span the entire execution, refer to our javascript guide to learn how to define a custom payload.

Scopes

Variables (with the exception of those defined using global) are always created within the executed scope. Take the following example:

{[ if trueOrFalse ]}
   {[ const variableInsideBody = "Text" /]}
   {{ variableInsideBody }}              // Properly executes
{[/]}

{{ variableInsideBody }}                 // Throws error

Since variables are scoped (and for flow creates a new variable within its body/scope), the substitution will fail because the variable was defined inside another body, out of scope.

Parent/child scopes are supported as well. Take this example:

{[ if trueOrFalse ]}
   {[ const variableInsideBody = "Text" /]}
   {{ variableInsideBody }}             // Properly executes
   {[ for number in numbers ]}
      {{ variableInsideBody }}          // Properly executes as well
   {[/]}
{[/]}

{{ variableInsideBody }}                // Throws error

Because for loop is inside the scope that was used to define variableInsideBody , we can use any property that was defined in parent scopes as well.

Null support

Null or empty values are handled gracefully, but most transformers consider them an error. You can check for whether a value is null by using @isNull(variable) function.

Last updated