Document toolboxDocument toolbox

This article is for Data Center. Visit Cloud

Expr Advanced Reference - Value Conversions

Each Expr function expects a value of a certain type to be passed as each of its parameters. (See Expr Function Reference.) When a value of a different type is encountered, an automatic conversion is attempted. If conversion is not possible, an error will result.

The conversion rules follow some basic principles:

  • Best effort is made to convert simple types, such as converting a text to a number
  • An item can be converted to text that represents it

  • Any value can be converted to an array of one element (array "wrapped around" a value)
  • An array with just one value can be converted to that value ("unwrapping" the array)

There are certain more specialized cases related to Text/Joined parameters, parameters marked as /Each and parameters of the User Function type.

The table below summarizes all the conversion rules.


Actual type → 

Required type ↓

NumberTextItemArrayKey-Value Mapundefined
Numberpass as is
  • empty string → undefined
  • try to convert to a number
  • if unsuccessful: error
use the item's text representation, according to the item type, and then use the rules for converting Text to Number
  • empty array → undefined
  • has only one element → try to convert that element
  • otherwise: error
errorundefined
Integer
  • use if an integer value
  • otherwise: error
same as above, and try to convert to integer
Date
  • same as above: timestamps are represented as "unix epoch milliseconds"
  • dates are represented as a timestamp of the corresponding day's midnight in the user's time zone
  • using non-integer values may result in error
Boolean
  • false if zero
  • true otherwise
  • false if empty or only whitespaces
  • true otherwise (including "0"!)
true
  • false if empty
  • true otherwise (including an array with 0 as an element)
truefalse
Textconvert to textpass as isuse the item's text representation,
according to the item type
  • empty array → undefined / empty text
  • has only one element → try to convert that element
  • otherwise: error
errorundefined / empty text
Text/Joinedsame as above
  • collect a Text (not a Text/Joined!) value for each non-undefined element
  • join elements into one string with ", " as a separator
same as above
Arrayarray with one elementarray with one elementarray with one elementpass as isarray with one elementundefined / empty array
Itemerrorerrorpass as is
  • empty array → undefined
  • has only one element → try to convert that element
  • otherwise: error
errorundefined
Key-Value Maperrorerrorerror
  • empty array → undefined
  • has only one element → try to convert that element
  • otherwise: error
pass as isundefined
Anyany value works

Text to Number Conversion

Some functions expect their arguments to be number values. In case an argument is a text value, we try to interpret it as a number. This can be useful if the value comes from a variable that represents a text custom field, which contains numbers — e.g., imported from some external system.

If conversion is successful, that number is used as the value for that argument. If conversion is not successful, functions can either produce an error, ignore that argument, or substitute some default — it depends on the function; see Expr Function Reference for details. 

The first step is to accommodate for variations in number formatting. Conversion supports these formatting symbols: 

  • Decimal fraction separators: comma (,), dot (.)
  • Digit group separators: comma (,), dot (.), apostrophe ('), space ()

Conversion expects that the text contains 0 or 1 decimal mark, and 0 or more group separators of the same kind. If the text contains any other formatting symbols, conversion fails. Decimal mark must come after all group separators, otherwise conversion fails.

If the text contains only one formatting symbol, and it's a dot (.), it is always treated as a decimal mark. If the text contains only one formatting symbol, and it's a comma (,), then it is treated as a decimal mark if a comma is used as a decimal separator mark in the Jira default language; otherwise, it is treated as a group separator.  For instance, if the default Jira language is English, "101,112" will become 101112, whereas if it is German locale, it will be 101.112. And regardless of language, "1 100,23" will become 1100.23: space is interpreted as a group separator, and comma can only be the decimal fraction separator here.

If the group separator is a dot (.), then all groups except the first one must have 3 digits; otherwise, conversion fails.

After determining decimal mark and group separator symbols, conversion removes all group separator symbols and replaces the decimal mark with a dot. Note that if text contains several whole numbers separated by spaces, conversion will think it is one number, for example, "10 11 12" will become 101112. Similarly, "10,11,12" will become 101112. 

The final step of conversion is to recognize the resulting text as either Expr's literal number representation or scientific or engineering notation. Examples:
0.239
-1.32e5
12e-3

Conversion to Boolean: Falsy and Truthy Values

A value is falsy if it is:

  • undefined,
  • number 0,
  • an empty text value ("" or ''), or a text value that contains only space characters,
  • an empty array.

All other values are truthy. 

When converting to a Boolean, truthy values become true and falsy values become false.

By convention, when functions or logical operators need to construct a truthy value, they use the number 1.

Text vs. Text/Joined

When a function declares that it requires "Text/Joined" value, it means that the value will be converted to a text, with an additional special handling of the array type:

  • If it's an empty array, or an array with only one element, the conversion will be the same as for "Text" type.
  • If an array with multiple values is passed, then a) each element of the array will be converted to a Text value, b) all these texts will be joined together with a comma as a separator. 

Here's an example illustrating the difference when fixVersion is passed as a parameter - notice that in the third row, there are multiple values in fixVersion (because it's an array), so Text and Text/Joined are treated differently:

fixVersion

Function accepting Text will receive

Function accepting Text/Joined will receive

(no value)undefinedundefined
v1"v1""v1"
v1, v2error"v1, v2"

Passing Implicit User Function as a Parameter

You can always pass an implicit User Function (the one containing the "$" symbol) as an argument to a function. This will result in the call to this function to become an implicit User Function value itself.

For example, consider the following expression:

fixVersions.FILTER(YEAR($.releaseDate) = 2021)

Function YEAR() expects a date, but it receives a User Function instead ($.releaseDate), which produces the release date for each passed version. As a result of applying YEAR() to that User Function, we will get another user function, which produces the year of the release date for each passed version.

This logic applies only to the implicit User Functions, defined with the $ sign.

The functions that expect a User Function parameter, like FILTER, are exclusions from this rule.

Variables

Variables (also known as free, or externally set variables) represent some values that will be fed into the formula for each Structure row that the formula will be applied to. 

For example:

IF priority = "Blocker" : parent.estimate + x

In this formula, "priority", "parent" and "x" are all variables – they vary from one row to another. (They will not change the value while calculating the expression for a single row.)

There's no need to declare a variable, you can immediately start using it. All valid identifiers that are used like variables will be treated as such.

Each formula is expected to contain at least one variable – otherwise, the result will be the same for each row.

Variable to Attribute Mapping

Each variable should be mapped to a valid attribute – such as a Jira field or a Structure attribute, so when an expression is calculated for a particular item, the value of that attribute becomes the variable's value.

If you use one of the well-defined variable names, it will be automatically mapped to the corresponding attribute. See Standard Variable Reference.

If you use an arbitrary variable name, such as "x", you will need to map it as described on the Mapping Variables page.

If a variable is not mapped, or if the item does not support the mapped attribute, the value of the variable will be the undefined value.

"this" Variable

One of the well-defined variable names is "this". It is mapped to an attribute that provides a value of Item type, representing the item for which the formula is being calculated.

This may come in handy in certain cases. For example, to analyze issue links and pick the "other side" of a link, regardless of whether it's an incoming or an outgoing link:

  • issueLinks.MAP(IF $.source = this : $.destination ELSE $.source)

Alternatively, you can use "item" with the same meaning.