Calculated expressions

What is a calculated expression?

Almost any card property with the primitive type (such as strings, numbers, and boolean expression) may refer to a calculated expression. The calculated part of the expression is written using the @{} construction and may contain variables, operators, and functions. View a list of supported functions in Embedded functions.

For example:

  • The "font_size": "@{common_text_size}" expression means the card font size property is calculated based on the common_text_size variable value.

  • To increase the font size only for certain cards relative to the same common_text_size variable, you can write the expression like this:

    "font_size": "@{sum(common_text_size, extra_size}"
    

    Now the expression adds up two variables' values using the built-in sum function. The same expression can be written using the + operator:

    "font_size": "@{common_text_size + extra_size}"
    

Restriction

You can't use expressions in card type properties, status IDs, or the variablesvariable declaration block.

Syntax of calculated expressions

Calculated expressions support the following constructions:

  • Logical operators: == , != , ! , > , >= , < , = , && , || .
  • Arithmetic operators: + , - , * , / , % .
  • Ternary operator: counter > 0 ? true : 'false' .
  • The !: operator: undefined_var !: fallback. If the calculation of the left side of the expression fails, then the right side is calculated.
  • Grouping logical expressions: logging_enabled && (user_name == 'John' || user_email != '') .
  • Function calls: mult(total_price, .83)
  • Using calculated parts within strings and string-type calculated expressions: "mail: @{'@{username}@ya.ru'}" is converted to mail: john@ya.ru

Template strings

Unlike other parameters, string parameters can contain multiple calculated parts, the values of which are converted to a string and substituted in the specified places. For example:

"url": "https://marketplace.yandex.ru/profile/@{user_name}/orders/@{order_id}"

In a calculated expression, you can use template strings that contain a constant part and nested calculated expressions:

"url": "@{'https://marketplace.yandex.ru/profile/@{user_name}/orders/@{order_id}'}"

How the expression value is calculated

The calculated expression value must have the same type as the property of the card the expression is used in. This means additional conversion of data types may be required when calculating an expression.

Calculating in string parameters

Let's say the parameter value is set by the following expression: "text": "@{sum(var_a, 50)}"

First the sum function's argument values are calculated, and then the result of the function.

The first argument is a link to a variable. To get its value, the variable is searched for first in local and then in DivContext variables.

Let's say var_a is an integer variable whose value is 25. The resulting number is added to the other argument, and the function result is 75. Then, in accordance with the text property context, this result is converted to a string, and the layout displays the text "75".

Calculating in string parameters with strict format

The color value can be set by a string with a specific format: "text_color": "#@{str_var}"

For such parameters, the string is converted to the parameter type: the result of the calculated expression is first converted to a string and then to the parameter type.

Calculating in fields with numeric values

Numeric parameters, such as text_size, don't support converting strings to numbers. That's why calculated expressions whose result matches the parameter type must be used in such parameters. For example:

  • Incorrect: "text_size": "10" , "text_size": "@{str_var}"
  • Correct: "text_size": "@{10}" , "text_size": "@{int_var}"

Calculating incorrect expressions

Let's say the height parameter has the numeric type. The parameter value is set via the @{toInteger('@{var_a}@{var_b}')} expression, where a template string with two variables is used. The result of the calculation is converted to a number using the toIntegerfunction.

Possible errors when using this expression:

  1. Variables don't exist.
  2. The toInteger function doesn't exist.
  3. The function doesn't support the String type argument.
  4. The value returned by the function is the incorrect type or violates the contract expected by the height field.

In all the situations listed above, the height value can't be calculated correctly, so the following attempts to avoid errors are used:

  • The attempt to calculate the expression with default variable values (for example, if the var_a variable value changed from 1 to one, and the toInteger function stopped working correctly.

  • The attempt to reuse the last successfully calculated value.

  • If there's no successfully calculated value, the expression takes the default parameter value (in this case, 0).

Data types in expressions

If variables are used in calculated expressions, then, depending on the situation, their values can be converted to internal types of calculated expressions.

The variable value is converted to an internal type if:

  • The variable is used in a template string
  • The variable is compared to the internal type value (the @{subscribed == true} expression returns true

The variable value isn't converted to internal type if:

  • The expression consists only of a link to the variable: "color": "@{color_var}"
  • Two variables of the same type are compared: @{color_var1 == color_var2}

Example:

{
    "variables": [
        {
            "name": "is_delivered",
            "type": "boolean",
            "value": true
        },
        {
            "name": "order_id",
            "type": "integer",
            "value": 17
        },
        {
            "name": "sum",
            "type": "number",
            "value": 381.3
        }
    ],
    "states": [
        ...
        {
            ...
            "text": "Order#@{order_id} delivered: @{is_delivered} total: @{sum}"
        }
        ...
    ]
}

In this example, expressions with non-string types of variables are used in a string. In this case, the variables' values are converted to strings. After calculating the variables' values, the text parameter looks like this: Order#17 delivered: true total: 381.3. Numeric variables were converted to a string without any changes, but the way the is_delivered boolean variable is displayed changed, and it's displayed as true instead of 1.

Internal types of calculated expressions

  • Integer : Integer type. Range: -2147483648..2147483647
  • Number : Floating-point number. Range: 4.9E-324..1.7976931348623157E308 (the Nan and Infinite values aren't supported)
  • Boolean : Boolean type. Possible values: true , false .
  • String : String.
  • DateTime : Date and time.

Rules for conversion to internal types

The values of string and numeric type variables are converted to the corresponding internal types. For the remaining variables, the following rules apply:

  • The color type is converted to a fixed-length string that looks like #ff001122.
  • The url is converted to a corresponding string.

Operations on types

  • All values of the same type can be checked for equality (== , != ).
  • Comparison operations are available for numeric and DateTime types (> , >= , < , = ).
  • Numeric types support all arithmetic operators, but note that operations on different types lead to errors. For example, the expression @{3.81 + 5} can't be calculated.

Learn more

Follow DivKit news in the Telegram channel: http://t.me/divkit_news

You can also discuss topics of interest in the DivKit user community in Telegram: https://t.me/divkit_community_ru

DivKit Repository