Skip to content

Derived Value

Derived values are an automatic way to update your variable values based on changes to selected data. We’ll use this schema and items model for demonstration:

var schema = {
id: {
type: NIMBUSDB_DATA_TYPE.INTEGER,
const: NIMBUSDB_CONSTRAINT.PRIMARY_KEY
},
name: NIMBUSDB_DATA_TYPE.STRING,
price: {
type: NIMBUSDB_DATA_TYPE.NUMBER,
validator: function(data, value) {
return value >= 0;
},
default_value: 0
},
is_locked: {
type: NIMBUSDB_DATA_TYPE.BOOLEAN,
const: NIMBUSDB_CONSTRAINT.OPTIONAL,
default_value: false
}
};
items = new NimbusDBModel("global", "items", schema, [
{ id: 1, name: "Apple", price: 5 },
{ id: 2, name: "Banana", price: 7.2 },
{ id: 3, name: "Cherry", price: 15 },
{ id: 4, name: "Date", price: 12.5 },
{ id: 5, name: "Elderberry", price: 8 },
{ id: 6, name: "Fig", price: 10 },
{ id: 7, name: "Grape", price: 6 },
{ id: 8, name: "Honeydew", price: 9 },
{ id: 9, name: "Kiwi", price: 4 },
{ id: 10, name: "Lemon", price: 3 }
]);

To create a derived value, you can use the .derived() method of the NimbusDBModel class.

// (1) on this instance variables
apple_price = items.derived("apple_price", 1, "price");
// the derived value refers to the "price" column of the data with primary key 1 in the "items" model
// so, `apple_price` will be 5
item_names = [
"Apple",
items.derived("item_names[1]", 2, "name"),
items.derived("item_names.2", 3, "name")
[
items.derived("item_names[2][0]", 4, "name")
]
];
item_names[4] = items.derived("item_names[4]", 5, "name");
// (2) on global variables
// add "global." or "g." prefix to mark it as global variable
global.apple_name = items.derived("global.apple_price", 1, "name");
global.item_names = [
"Apple",
items.derived("g.item_names[1]", 2, "name"),
items.derived("global.item_names.2", 3, "name")
[
items.derived("global.item_names[2][0]", 4, "name")
]
];
// later, you can update the data
items.update_by_primary(1, {
name: "Bad Apple",
price: 10
});
// after updating the data, the derived value will be updated automatically
// `apple_price` variable will be 10, `global.apple_name` will be "Bad Apple", etc.
// works for arrays and objects too

Using derived values on object fields need extra care, so you won’t get undefined value even if the data/method is used properly.

some_var = {
normal: items.derived("some_var.normal", 1, "name"),
arr: [items.derived("some_var.arr[0]", 1, "name")],
nested: {
price: items.derived("some_var.nested.price", 2, "price"),
arr: [items.derived("some_var.nested.arr[0]", 2, "name")]
}
}
// if you access any field of `some_var` in this frame, you will get `undefined` value
var item1_name = some_var.normal; // undefined
// also happens for other fields under `some_var`
var item2_name = some_var.arr[0];
// (1) set a callback function to be called when the data is updated
// set `on_update` option to enable this
apple_price = items.derived("apple_price", 1, "price", {
on_update: function(data, new_val, old_val, prop) {
show_debug_message($"`apple_price` has been updated to {new_val}");
},
immediate: true // in case you want to call the callback immediately after creation
});
// (2) variable name shortening for nested objects
// set `ref` option to enable this
some_var = {
nested: {
nested_again: {
some_var: 0
}
}
}
// instead of this:
some_var.nested.nested_again.some_var = items.derived("some_var.nested.nested_again.some_var", 1, "name");
// you can do this:
some_var.nested.nested_again.some_var = items.derived("nested_again.some_var", 1, "name", {
ref: some_var.nested
});
// or this:
some_var.nested.nested_again.some_var = items.derived("some_var", 1, "name", {
ref: some_var.nested.nested_again
});
  • Derived values only work on instance variables and global variables. So, local variables are not supported.
  • Both var_name[index] and var_name.index are supported for array.
  • You can use derived values on arrays up to 3D (i.e. var_name[index][index][index]).
  • Object can contain arrays, but arrays can’t be nested inside objects.
    obj = {
    normal: items.derived("obj.normal", 1, "name"),
    // arrays inside objects are supported
    arr: [items.derived("obj.arr[0]", 1, "name")],
    nested: {
    arr: [items.derived("obj.nested.arr[0]", 2, "name")]
    }
    };
    arr = [
    items.derived("obj[0].normal", 1, "name"),
    [ items.derived("obj[1].arr[0]", 2, "name") ],
    // but objects inside arrays are not supported
    { some_prop: items.derived("obj[0].some_prop", 1, "name") },
    {
    arr: [items.derived("obj[1].arr[0]", 2, "name")],
    nested: {
    arr: [items.derived("obj[1].nested.arr[0]", 3, "name")]
    }
    }
    ]

The NimbusDBDerived class is used to define derived values in NimbusDB models.

reactivity.d.ts
class NimbusDBDerived {
constructor(
_inst_id: Instance | "global",
_var_name: string, // use "global" or "g" prefix to use global variable
_model: NimbusDBModel,
_data: Struct, // from data
_watch_column?: string | string[],
_options?: NimbusDBDerivedConstOptions
)
data: Struct;
id: int;
last_val: any;
prop_name: string;
var_name: string; // variable name in ref
on_update?: ( // called when the data is updated
data: Struct,
new_val: any,
old_val: any,
prop: string
) => void;
static refresh: () => void;
static update: () => void;
static __id: int;
__inst: Instance | "global";
__model: NimbusDBModel;
__ref: Instance | Struct | "global"; // root reference
__source?: NIMBUSDB_DERIVED.SOURCE_INSTANCE | NIMBUSDB_DERIVED.SOURCE_GLOBAL | NIMBUSDB_DERIVED.SOURCE_STRUCT;
__target?: NIMBUSDB_DERIVED; // .TARGET_*
__indexes?: int[];
__sys_temp?: Struct;
__reinit_count: int;
static __init: () => void;
}

Creates a derived value from watched model data.

model.d.ts
class NimbusDBModel {
// ... other methods and properties ...
static derived(
_var_name: string,
_original_data: int | NimbusDBData,
_watch_column: string,
_instance?: Instance
): any;
}
  • Type: string
  • The name of the variable to bind to.
  • Type: int | NimbusDBData
  • The original model data reference (direct-access data) or primary key of the data.
  • Type: string
  • The column to watch for changes.
  • Type: Instance
  • The instance reference to bind the derived value to.
  • Type: any
  • The value of a column from the related data.

NimbusDBDerivedConstOptions Internal

Section titled “NimbusDBDerivedConstOptions ”

An optional configuration object for the NimbusDBDerived constructor.

reactivity.d.ts
type NimbusDBDerivedConstOptions = Partial<{
ref: Instance | Struct | "global"; // override NimbusDBModel.__root
on_update: ( // called when the data is updated
data: Struct,
new_val: any,
old_val: any,
prop: string
) => void;
}

An optional configuration object for the NimbusDBModel.derived() method.

reactivity.d.ts
type NimbusDBDerivedOptions = Partial<{
inst: Instance | "global"; // override NimbusDBDerived.__inst
immediate: boolean; // call .on_update immediately after creation (default = false)
ref: Instance | Struct | "global"; // override NimbusDBDerived.__sys_temp.ref
return_id: boolean; // return the id of the data instead of the data (default = false)
on_update: ( // called when the data is updated
data: Struct,
new_val: any,
old_val: any,
prop: string
) => void;
}>;

An enum that defines the source and target of a derived value.

reactivity.d.ts
enum NIMBUSDB_DERIVED {
SOURCE_INSTANCE = 1,
SOURCE_GLOBAL,
SOURCE_STRUCT,
TARGET_INSTANCE = 1,
TARGET_INSTANCE_ARRAY_1D,
TARGET_INSTANCE_ARRAY_2D,
TARGET_INSTANCE_ARRAY_3D,
TARGET_GLOBAL_STRUCT,
TARGET_GLOBAL_ARRAY_1D,
TARGET_GLOBAL_ARRAY_2D,
TARGET_GLOBAL_ARRAY_3D,
TARGET_STRUCT,
TARGET_STRUCT_ARRAY_1D,
TARGET_STRUCT_ARRAY_2D,
TARGET_STRUCT_ARRAY_3D
}