Functions

Functions are the building blocks of InterActor dashboards and applications. They perform actions such as loading data or displaying information, and can be linked to each other through Triggers. Triggers are executed at specified moments in the Function's processing, or initiated by user input, and result in the execution of linked Functions. The Triggers can carry data between one Function and the next.

Both Functions and Triggers are stored in the Neo4j graph store, with Functions represented as nodes and Triggers as relations between those nodes. the InterActor Function nodes all have a :IA_Function label, besides another label that indicates the function type. So you will find nodes with labels like :IA_Function:IA_Neo4jQuery and :IA_Function:IA_NetworkView. The Trigger relations have the relation type :TRIGGER, (:SHORTCUT or :START if connected from a dashboard).

Each Function has a set of features in common: they inherit these from the general Function definitions. A special subset of Functions are Views, they also share a set of common features, inherited from the general View definitions.

Executing

A Function can be executed by a Trigger (coming from another Function, or from the User Dashboard). When a Function is executed, it performs the action it is designed to do, and fires outgoing Trigger events when it is done. In the following example, a TableView is executed by the 'success' Trigger event from a Neo4jQuery:

Function-Trigger-Function example

During execution, the Function may fire outgoing Trigger events, which can cause connected Functions to be executed as well.

Parameters

Each Function can behave differently, based on certain parameters. For example, a Neo4jQuery can execute a cypher query that is passed to it as the cypher parameter value. These values can be set on the Function, incoming Trigger, or user prompt. The parameter values are checked for validity and stored in the Function, and can be accessed later. More information on parameters can be found here.

Function instances and updating

By default, a Function will be executed. This means that an instance of the Function is created, performs its actions, fires outgoing Trigger events and, once it is done, it is destroyed. The Function node remains; this is merely a 'description' based on which new instances are created. A Function can be executed again and again, each time creating a new instance and destroying it after it has finished its processing.

A Function instance can also be told to persist after execution (using the $stayAlive: dashboard parameter), keeping its data available for further processing after user input or when other Functions finish execution. Multiple instances of the same Function can co-exist. While an instance exists, it can be updated through Update Triggers. Update Triggers are similar to regular Triggers, except they specify instances of the target Function that should be updated, instead of creating a new one. The instance is specified using the $_instance parameter, which can take one of the following values:

  • _all: all open instances of the Function are updated.
  • _previous: the last Function instance on the execution path is updated.
  • Any other string: the instance with the given string as its name is updated. If it does not exist, it is created.

If the $_instance parameter is specified, a targeted instance of the Function is created (if it does not exist) or updated (changing the data instead of creating new instances every time).

If the $_instanceUpdateOnly parameter is set to true, the trigger will not create a new targeted (with $_instance) instance of a function if it does not yet exist.

While a Function instance is open, its state can be accessed from each outgoing Trigger, as further described here.

List updates

For parameters that are lists, there is a special parameter #_update available, that allows updates to specific items in the list. The #_update parameter can contain one or multiple of the following properties:

  • add: adds items to the list
  • remove: removes items from the list
  • set: adds or replaces items in the list
  • change: alters items in the list
Example: add

Suppose a Function parameter called myList contains a list of numbers: [1,2,5]. We use the #_update.add parameter to add values 3 and 5 to the list:

#_update.add.myList: [3,5]

The resulting list in myList will be: [1,2,5,3,5]. Note that there is no check for uniqueness, nor is the new list ordered. The other operators (remove, set, and change) do need to check for existing identical values.

Example: remove

Suppose a Function parameter called myList contains a list of numbers: [1,2,5]. We use the #_update.remove parameter to remove the value 2 from the list:

#_update.remove.myList: [2]

The resulting list in myList will be: [1,5]. All occurrences of the number 2 are found in the list and removed.

Value identification

The operators set, remove and change, need to find existing values in the list to either replace, remove or change them. In order to do this, the values in the list are compared to the values that are specified in the operator, to see if they are considered equal. Two values are considered equal if one of the following conditions hold:

  • They are exactly the same (for simple values such as strings, numbers and booleans)
  • The id properties of both values are exactly the same (in case both values are objects)
  • All properties of both values are exactly the same (in case both values are objects)
Example: change object

Suppose a Function parameter called myList contains a list of objects:

[
	{id: 15, name: 'Hank', age: 47},
	{id: 7, name: 'Florence', age: 21},
	{id: 51, name: 'Eddie', age: 35}
]

We use the #_update.change parameter to change Eddie's name to Ed:

#_update.change.myList: [{id:51, name:'Ed'}]

The change operator finds the object with id 51 in the list, considers it equal to the given object, and changes the name property to "Ed".

Use of change vs set

The change and set operators seem similar, in the sense that they can both change a value in the list. Consider the 'change object' example above. Suppose we want to change Eddie's information again, and use either:

#_update.set.myList: [{id:51, name:'Ed'}]

or

#_update.change.myList: [{id:51, name:'Ed'}]

The set operator will find the object with id 51 in the list, and replace it with the new object. Note that the new object does not contain an age property. Since the entire object is replaced, we have changed the name, but also removed the age property. On the other hand, the change operator will find the object with id 51 in the list, and merge the objects, i.e. replace only the properties that are defined in the new object. No properties will be removed.

The other difference is that the set operator will add the new object if no existing object with id 51 was found, whereas the change operator will not.

Caching

Each Function execution usually makes a call from your browser to InterActor. If the connection between the user and InterActor is slow, a significant performance boost can be achieved by caching the the Function calls. When Functions are cached, a page refresh is required to update dashboard functionality after a Function change. This is not recommended when you are in the process of developing a dashboard.

Caching can be switched on or off per user by setting the caching property on the :IA_User node to true. Caching is switched off by default.