Variables store data values. They are declared with the var
keyword and may be assigned any value. Variables must be declared, and identified with a name. The identifier must adhere to the following rules:
- begins with a latin letter, underscore, or $
- contains only latin letters, latin numbers, underscore, or $
- must not match any reserved words.
As a guideline, variable names should not begin with $
as that pattern is reserved for profile variables. Identifiers are not case-sensitive.
Declaring variables
A variable can be declared with a literal (or fixed) value.
// variable as number literal
var x = 10;
// variable as text literal
var name = "Dave";
// variable as date literal
var startDate = Date(2015,0,1);
// variable as boolean literal
var likesArcade = true;
Variables can be declared with expressions. In this scenario, the variable stores the computed value.
var total = 100 + 50;
// the value of total is 150
var first = "Paul";
var last = "Richard";
var fullName = first + " " + last;
// the value of fullName is "Paul Richard"
You can declare variables with no value, and assign their value later in the expression.
var x; var y;
x = 100;
y = 50;
return x+y;
// output is 150;
Value reassignment
Variables may be reassigned to new values at any point in the expression;
var age = 35;
var birthday = Date(1980, 5, 2);
// computes the age based on the time the expression was executed
age = Round( DateDiff(Now(), birthday, "years") );
Variables can be re-assigned new values of different types.
// declared as a number
var age = 35;
// reassigned as text
age = "35 years";
Remember, variables must be declared. The following will result in a compilation error.
age = 35;
// age has not been declared with var
Profile variables
Profile variables are data values provided as input to every Arcade expression written in a given profile. Profile variables always begin with the $
character. The profile variables available to an expression depend on the profile specification.
For example, the $feature
profile variable represents a feature - its attributes and geometry - which may be used in an expression. This is available in most profiles as a way to calculate values from a feature's attributes.
Dot notation
You can access feature attributes using dot notation: (e.g. $feature.field
).
// returns % of population with a college degree
var percentCollege = Round(($feature.COLLEGE / $feature.POPULATION) * 100, 2);
// returns the population density per square kilometer
var popDensity = Round( $feature.POPULATION / AreaGeodetic(Geometry($feature), "square-kilometers") );
Bracket notation
Attribute and dictionary values can also be referenced using square brackets.
// returns % of population with a college degree
Round(($feature["COLLEGE"] / $feature["POPULATION"]) * 100, 2);
Bracket notation must be used when referencing any of the following:
- values from joined tables (e.g.
$feature["join
)Key.field Name"] - unusual field names, such as non-Latin characters outside the Unicode BMP
- field names using variables
// returns % change in votes from 2012 to 2016
// The data referenced in this expression comes from a table join
Round((($feature["COUNTY_ID.VOTED_DEM_2016"] - $feature["COUNTY_ID.VOTED_DEM_2012"]) / $feature["COUNTY_ID.VOTED_DEM_2012"]) * 100, 2);
Some expressions dynamically reference field names with variables rather than text literals.
// Assuming fields are named Population_1900, Population_1910, ..., Population_2000
var start = 1900;
var end = 2000;
var trends = [];
for (var i = start; i <= end; i+=10){
var current = $feature[`Population_${i}`];
var previous = $feature[`Population_${i-10}`];
var trend = (current - previous) / previous;
Push(trends, trend);
}
return Average(trends);
While convenient, this makes it difficult for client rendering and labeling engines to detect and request data from fields required for rendering based on the expression. To ensure the data is properly requested from the datastore, either reference the field name as a text literal...
// Assuming fields are named Population_1900, Population_1910, ..., Population_2000
var trends = [
$feature["Population_1900"],
$feature["Population_1910"],
$feature["Population_1920"],
$feature["Population_1930"],
$feature["Population_1940"],
$feature["Population_1950"],
$feature["Population_1960"],
$feature["Population_1970"],
$feature["Population_1980"],
$feature["Population_1990"],
$feature["Population_2000"]
];
return Average(trends);
...Or use the Expects function. This function allows you to explicitly indicate required fields as a list. You can also request all or a subset of fields using a wildcard, giving you the convenience to write more generic expressions.
// Assuming fields are named Population_1900, Population_1910, ..., Population_2000
Expects($feature, "Population_*");
var start = 1900;
var end = 2000;
var trends = [];
for (var i = start; i <= end; i+=10){
var current = $feature[`Population_${i}`];
var previous = $feature[`Population_${i-10}`];
var trend = (current - previous) / previous;
Push(trends, trend);
}
return Average(trends);
Generally, it is best practice to explicitly list all field attributes that will be used at the top of the expression.
Scope
Scope determines whether a variable is accessible in certain parts of the expression.
Global scope
Variables declared outside a function have global scope through the expression. That means you can use a variable anywhere in the expression, inside or outside functions and blocks as long as it is after the variable is declared.
var baseValue = 10; // this var has global scope
function isGreater (x) {
return x > baseValue; // it can be used inside a function
}
Console(baseValue) // and referenced outside a function
return isGreater(100);
Local scope
Variables declared inside a function have local scope. They can only be used inside the function definition.
var baseValue = 10; // this var has global scope
// x has local scope
function isGreater (x) {
// it can only be used inside the function
return x > baseValue;
}
Console(x); // this will throw an error;
return isGreater(100);
var baseValue = 10; // this var has global scope
function isGreater (x) {
var factor = 2; // factor and x have local scope
return (x * factor) > baseValue;
}
return isGreater(100);
Variables declared inside functions can override global scope variables.
var myGlobal = 1;
function useGlobal() {
var n = 10; // n has local scope
return myGlobal * n; // will return the globally defined variable
}
function overrideGlobal() {
var myGlobal = 1000;
return myGlobal * 10; // will use the locally defined myGlobal variable
}
var z = overrideGlobal(); // returns 10000
var k = useGlobal(); // returns 10
return z + k; // returns 10010
Block scope
Arcade does not support block scope. This means variables defined inside a control block (i.e. if or for) will be available outside the block.
var myGlobal = 1;
for(var k=1; k<100; k++) {
var n = 10; // Defined in block, still available outside the block.
}
return k + n; // returns 110