Skip to main content

Understanding Variable Dependencies

This page explains how variable dependencies work in the EntityModel and how they affect variable and EntityField calculation.

VariableGraph - How dependencies between variables work

The VariableGraph is an internal data structure which tracks the dependencies between JDito variables.

How dependencies are created

Dependencies inside the VariableGraph are created when a JDito process reads variables through vars.get()/vars.getString() or when it explicitly declares dependencies using vars.dependOn().

  • vars.get() inside a valueProcess or other variable-bound process creates a dependency.
  • When the source variable changes, the VariableGraph marks variables which dependend on it as invalid. However, the dependent variables are not recalculated immediately.
  • The next time the value of a dependent variable is retrieved, it will be recalculated. Note: Every execution of the JDito process can redefine the dependencies of the variable.
import { result, vars } from "@aditosoftware/jdito-types";

let total = vars.get("$field.AMOUNT") * vars.get("$field.UNITPRICE");

result.string(total);

This example process reads the AMOUNT and UNITPRICE fields, creating dependencies on both. When either field changes, the result will also be updated when this field is loaded.

Not all processes are part of the VariableGraph

The system only tracks dependencies of JDito processes if the result can be accessed as a variable, such as entity fields and parameters.

This does not apply to one-time processes with a clearly defined trigger for execution (examples: recordContainer processes, onInit, afterSave, onValueChange).

Avoid recursion

Recursion occurs when a process reads and writes variables in a way that creates a circular dependency. Make sure a field valueProcess doesn't depend on itself or a variable that already has a (transitive) dependency on that field.

Date variables

Date variables receive special handling in JDito because time is not a stable dependency source.

  • Time-dependent values are not part of the normal VariableGraph.
  • A dependency on a date-like variable cannot be tracked in the same way as a variable that changes explicitly.

The following variables will not create a dependency:

  • sys.date
  • sys.staticdate
  • sys.dynamicdate
  • sys.staticmillis
  • sys.today

vars.dependOn()

(available in version 2026.1.0)

vars.dependOn(...pNames) explicitly registers dependencies for the current process. It can be used when your process must be recalculated because a variable changes, but the exact value of that variable is not used.

Don't use this method when:

  • the variable is already retrieved with vars.get() or vars.getString(), these methods will automatically create a dependency.
  • the process is not part of a variable (e.g. onActionProcess). It will have no effect.

Example:

// Not recommended: using vars.get just to create a dependency
// this would work, but readability is bad because the intention is unclear
vars.get("$field.STATUS");

// With vars.dependOn, the purpose of this statement is obvious
vars.dependOn("$field.STATUS");

vars.dependOnRowChange()

(available in version 2026.1.0)

vars.dependOnRowChange() registers a dependency on the currently loaded record. This is relevant where multiple rows are processed one after another, like in a table. Calling this method in the current process will ensure that it is recalculated for every single row, even if the other dependencies of the process remain unchanged.

Don't use this method if you already have a dependency on a variable that is unique for every row, for example the UID. Only use it when you are absolutely sure that it is necessary for correct result values, because it will have a negative impact on performance.

info

If the preference setting neonRowRecalculationMode is set to LEGACY_RESET_FIELD_VALUES_ON_ROW_CHANGE, the value is always recalculated for every row. vars.dependOnRowChange() is only effective when REUSE_FIELD_VALUES_ON_ROW_CHANGE is activated.

Example: Table Row Calculation

This theoretical example shows how the usage of vars.dependOnRowChange affects the process execution when loading multiple rows for a table.

Setup

There are three EntityFields in this Entity:

  1. UID - The unique row identifier, filled by the RecordContainer
  2. RANDOM_STATIC - The valueProcess returns a random number and it has no dependencies
  3. RANDOM_ROW_DEPENDENT - Also a random number, but the valueProcess creates a row dependency using vars.dependOnRowChange()

This is the valueProcess for RANDOM_STATIC:

import { result } from "@aditosoftware/jdito-types";

let randomInt = Math.floor(Math.random() * 100);

result.string(randomInt);

And this is the valueProcess for RANDOM_ROW_DEPENDENT:

import { result, vars } from "@aditosoftware/jdito-types";

vars.dependOnRowChange();

let randomInt = Math.floor(Math.random() * 100);

result.string(randomInt);

The resulting table may look like this:

UIDRANDOM_STATICRANDOM_ROW_DEPENDENT
13776
23739
33715
4374
53712

Because the first process has no dependencies on any other variables, the value is calculated only once, and then re-used for every following row.

In contrast, the second process is executed for each row, resulting in different values for all rows.