Calculated attribute configuration
This functionality is available for Creatio 8.3.2 and later.
Calculated attributes are configuration objects defined inside the viewModelConfig schema section. They provide a declarative way to compute values in the view model. Learn more: Working with calculated attributes.
The configuration object specifies:
- input view model attributes or requests used in the calculation
- transformation and conditional logic
- events that trigger recalculation
- optional reactions to calculated value changes
Calculated attributes have no setter and cannot be assigned directly.
View the configuration object that lists all supported properties.
{
from?: string | string[];
converter?: ConverterExpression;
filter?: ConverterExpression;
change?: RequestConfig | RequestConfig[];
triggers?: CalculatedAttributeTriggerConfig[];
triggersOptions?: {
debounce: number;
};
}
Not all properties are required. Depending on the scenario, a calculated attribute can be defined using only a subset of the available properties. Some controls do not support binding calculated attributes. For example, binding a calculated attribute to the crt.Input control is not supported.
Properties
from?: string | string[];
Defines the source attribute or request names used as input for the calculated attribute. Required for a calculated attribute if neither converter nor triggers is specified.
If the from property references an attribute:
- The initial calculation occurs after all source attributes have values.
- Recalculation is triggered when any source attribute changes.
- Attribute subscriptions are created after the first
getterinvocation.
If the from property references a request:
- The initial calculation occurs after all source requests have executed at least once.
- Recalculation is triggered on each subsequent request execution.
- Request subscriptions are created at configuration time.
Request subscriptions are created at configuration time to ensure that request execution results are captured even if the calculated attribute is accessed later. If a request is executed before the calculated attribute getter is called, the most recent request value is used during calculation.
The from property cannot include both attributes and requests. Both from and triggers can be empty, provided that a converter is defined.
converter?: ConverterExpression;
Defines the transformation logic applied to source values. Required for a calculated attribute if triggers is specified and from is not defined.
The converter expression:
- receives input values from
from(if specified) - transforms input values into the calculated attribute value
- can be defined as a chain of
converterexpressions.
If from is omitted, the converter acts as a standalone function and computes the value on demand.
filter?: ConverterExpression;
Defines a conditional expression that controls whether the calculation is executed. Optional.
The values of the attributes or requests specified in from are provided as input parameters to the filter expression.
When the filter property is used with request-based sources, a request accumulation is applied. When calculated attributes use request-based sources together with a filter, request invocations are accumulated until the calculated attribute is accessed.
This behavior is required because calculated attributes are evaluated lazily and the filter is applied only during getter invocation.
The accumulation mechanism works as follows:
- Request invocations specified in
fromare stored until the calculated attributegetteris called. - To limit memory consumption, up to 100 request invocations are accumulated.
- When the buffer reaches the limit or when the
getteris invoked, stored requests are evaluated in reverse order, starting from the most recent. - The first request that satisfies the filter condition is used for calculation.
- After a valid request is found, the buffer is cleared and accumulation stops.
- After
getterinvocation, accumulation is reset and starts again on the next access to the calculated attribute.
If triggers is specified and from is not specified, the filter expression is ignored.
If specified:
- the filter expression is evaluated before the
converter - calculation is skipped if the filter condition is not satisfied
- the filter receives the same input values as the converter
change?: RequestConfig | RequestConfig[];
Defines one or more requests to execute when the calculated attribute value changes. The specified request(s) are executed after the calculated attribute value is updated. This can be useful when additional business logic needs to be executed after the calculated attribute changes, for example, to perform further calculations or update another attribute. Optional.
triggers?: CalculatedAttributeTriggerConfig[];
Defines additional events that trigger recalculation of the calculated attribute. Optional.
If specified:
- Recalculation occurs when defined attributes change or when specified requests are executed.
frombecomes optional. Iffromis omitted, the initial calculation occurs on the firstgetterinvocation.
When recalculation is triggered by the triggers property, request accumulation is not applied.
Triggers can be configured to react to the following events:
-
Attribute changes. Recalculation is triggered when specified attributes change, regardless of whether they are listed in
from.{
attribute: string;
filter?: ConverterExpression;
} -
Request executions. Recalculation occurs when specified requests are executed, independently of those defined in
from. Request accumulation is not applied.{
request: string;
filter?: ConverterExpression;
} -
Filtered conditions. A trigger can include an optional
filterto ensure recalculation occurs only when specific criteria are met. When an attribute changes or a request is executed, thefilter(if defined) is evaluated first. If the condition is satisfied, the calculated attribute is recalculated using the latest available values.
triggersOptions?: {
debounce: number;
};
Defines trigger behavior options. Optional.
Parameters
debounce | Specifies a delay in milliseconds before recalculation starts to reduce recalculation frequency during rapid changes. |
Usage examples
View the example that defines the FullName calculated attribute based on the Name and Surname attributes without specifying a converter.
{
"viewModelConfig": {
"attributes": {
"FullName": {
"from": [
"Name",
"Surname"
]
}
}
}
}
View the example that defines the FullName calculated attribute based on the Name and Surname attributes.
{
"viewModelConfig": {
"attributes": {
"FullName": {
"from": [
"Name",
"Surname"
],
"converter": "usr.Concat"
}
}
}
}
View the example that defines the ActivePerson calculated attribute based on request execution results. In this example, ActivePerson depends on the results of the usr.ListActiveRowChanged and usr.ListItemsChanged requests. When either request is executed, the attribute is recalculated. The usr.ToValueByIndex converter returns the element at the specified index of the request result array. Therefore, ActivePerson contains the element returned by the converter.
{
"viewModelConfig": {
"attributes": {
"ActivePerson": {
"from": [
"usr.ListActiveRowChanged",
"usr.ListItemsChanged"
],
"converter": "usr.ToValueByIndex"
}
}
}
}
View the example that defines the GeneratedId calculated attribute using a standalone converter.
{
"viewModelConfig": {
"attributes": {
"GeneratedId": {
"converter": "usr.GenerateUUID"
}
}
}
}
View the example that defines the Result calculated attribute based on a request and applies conditional calculation using a filter.
{
"viewModelConfig": {
"attributes": {
"Result": {
"from": "usr.Request",
"filter": "usr.Modulus : 5 | crt.IsEqual : 0",
"converter": "usr.Divide : 5"
}
}
}
}
View the example that defines the FullName calculated attribute with attribute-based sources and conditional execution.
{
"viewModelConfig": {
"attributes": {
"FullName": {
"from": "Name",
"filter": "crt.IsEqual : '' | crt.InvertBooleanValue",
"converter": "usr.Concat : 'Nova'"
}
}
}
}
View the example that defines the FullName calculated attribute and executes a request when the calculated value changes.
{
"viewModelConfig": {
"attributes": {
"FullName": {
"from": "Name",
"converter": "usr.Concat : 'Nova'",
"change": [
{
"request": "usr.CalculatedAttributeChangeRequest",
"params": {
"targetAttributeName": "Surname"
}
}
]
}
}
}
}
View the example that defines the TimeNow calculated attribute and recalculates the value when a request is executed.
{
"viewModelConfig": {
"attributes": {
"TimeNow": {
"converter": "usr.TimeNow : 'mm:ss'",
"triggers": [
{
"request": "usr.RefreshTimeRequest"
}
]
}
}
}
}
View the example that defines the TimeNow calculated attribute, performs the initial calculation after a request execution, and recalculates the value on another request.
{
"viewModelConfig": {
"attributes": {
"TimeNow": {
"from": "usr.StartTimerRequest",
"converter": "usr.TimeNow : 'mm:ss'",
"triggers": [
{
"request": "usr.RefreshTimeRequest"
}
]
}
}
}
}
View the example that defines the TimeNow calculated attribute with trigger debounce applied.
{
"viewModelConfig": {
"attributes": {
"TimeNow": {
"converter": "usr.TimeNow : 'mm:ss'",
"triggers": [
{
"request": "usr.RefreshTimeRequest"
}
],
"triggersOptions": {
"debounce": 300
}
}
}
}
}