Triggers

Triggers are used to start new Function instances or modify existing ones. They take place at specific events in a Function and carry information to another Function. For example, a Neo4jQuery can trigger a TableView to visualize its results.

When an event occurs in a Function, an event data object is created. This object contains data such as the type of event, the state of the Function and event-specific information. Two steps are then performed with this data:

  1. Trigger matching: Matching Triggers are found by comparing the Trigger properties to the event data properties. For example, a Trigger with the property type: "success" will only be executed if the event data has that same property and value. Matching Triggers are executed and receive the event data.

  2. Data mapping: When a Trigger is executed, it can map parts of the data from the event to the receiving Function.

The Trigger is defined by a :TRIGGER relation from the source :Function node to the target :Function node. The :TRIGGER relation has two types of properties:

  1. Properties starting with either # or $ are used for data mapping .
  2. All other properties are used for Trigger matching; they are matched against the event data to determine whether the Trigger should be executed.

Example 1 has a very simple Trigger from a Neo4jQuery to a TableView. The image below is a visualization of Trigger, with the Neo4jQuery in blue and the TableView in green.

(n:IA_Neo4jQuery)-[r:TRIGGER{type:'success']->(m:IA_TableView))

The properties of the :TRIGGER relation are:

Key Value Explanation
type success This tells the Trigger to only execute if the Neo4jQuery was successful.
#data (%).data This tells the Trigger to pass the query results to the #data parameter property of the TableView.

As a result, upon a successful query, the Neo4jQuery will match and execute this Trigger based on type: "success". The results of the query are passed in the event data to the Trigger, which passes it to the TableView's #data parameter.

Events

Each Function has its own set of possible events. For example, an event occurs when a Function is executed, when the user clicks somewhere in a view, when a Function completes an automated action, etc.

The event carries data in an object, containing multiple properties. Some properties can be found in every event, others differ per event type. One property that is always present in an event is the type property, which specifies the type of event that occurred (e.g. functionExecuted, nodeClick, rowClick, etc). Other properties are defined by each Function independently for specific events. Property values can be of many types, from a string to an array or nested objects.

Trigger matching

To execute a Trigger upon events, a :TRIGGER relation needs to be specified, starting at the source Function (causing the Trigger event), and ending at the target Function (which is to be executed or modified). In order to specify at which events the Trigger should be executed, properties can be defined that need to match data in the Trigger event. The most important specification is that of the type property. By setting a type property to a certain value in the :TRIGGER relation, the Trigger will only execute upon events of that type. The more properties are defined in the relation, the more conditions the event will have to fullfil in order to execute the Trigger.

If no properties are defined in a `:TRIGGER` relation, the Trigger will execute upon any event occurring in the source Function.

Example

From a TableView we would like to open an (empty) NetworkView when the user clicks a row. Let's say, in a particular TableView, the Trigger data would contain (at least) the following properties:

{
    "type": "rowClick",                   // 'type' is always 'rowClick'
    "data": {                             // 'data' contains the data from the clicked row
        "name": ... ,                     // these key-value pairs are the column names paired with the corresponding value of the clicked row
        "city": ...
    }
}

If we wanted the empty NetworkView to open at any rowClick, the :TRIGGER relation from the TableView to the NetworkView should contain exactly the following property (nothing more, nothing less):

Key Value Meaning
type rowClick Only execute this Trigger when the event has the type: rowClick property.

If we wanted the empty NetworkView only to open if a row with a specific value for a specific column is clicked (let's say city: "Amsterdam"), we add a specification for city property, which is nested in the data object. The resulting :TRIGGER properties would be these:

Key Value Meaning
type rowClick Only execute this Trigger when the event has the type: rowClick property.
data.city Amsterdam Only execute this Trigger when the event the city property in the data property in the event as the value Amsterdam.

Data mapping

When triggering a new Function, we can pass data to configure it. For example, we can pass nodes and relations to a NetworkView to make it visualize them or pass parameters to a Neo4jQuery to be inserted into its cypher statement.

Every Function has predefined 'parameter' properties that act as receivers for data. See the Functions section for overviews of parameter properties for each Function. These parameter properties can be given a value by incoming Triggers, by creating a mapping from the Trigger data to the Function parameters. Like the Trigger matching, this mapping is defined in the :TRIGGER relation properties.

To distinguish the data mappings from the Trigger matching properties (see section above), data mapping properties are prefixed with either a $ (for single values) or # (for arrays). Properties starting with this prefix are not interpreted as Trigger matching properties and do not determine when the Trigger will be executed. Instead, they specify which Trigger data should be mapped to which parameter property in the receiving Function.

In the Trigger, the event data can be accessed using the notation (%). This refers to the event data object. From there, we can specify the event property we wish to map to a parameter property of the Target Function. In case the property we are looking for is nested inside one or multiple objects in the Trigger data, we can specify the path to the property with dots in between (e.g. (%).person.name would refer to the name property inside the person property inside the Trigger data object.).

In the data mapping, the property key specifies a parameter property of the target Function. The property value of the mapping specifies which property from the source Function's Trigger data should provide the data for that parameter property in the target Function.

Example

A SearchView fires a Trigger event when the user clicks 'Execute' in the SearchView panel. This event has at least the following properties:

{
    "type": "execute",
    "data": {
        "query": "...",
        "output": "..."
    }
}

A Neo4jQuery has a $cypher parameter property, which expects a cypher statement (string). If we wish to execute a Neo4jQuery with a cypher statement entered in a SearchView, we would connect a Trigger from the SearchView to the Neo4jQuery, with the following properties:

Key Value Meaning
type execute Only execute this Trigger when the event has the type: execute property.
$cypher (%).data.query Pass the value at the data.query path to the $cypher parameter property of the Neo4jQuery.

In this example, the "type": "execute" property specifies that this Trigger should only be executed in an event with "type": "execute" (which is when the user clicks the 'Execute' button) and the "$cypher": "(%).data.query" property tells the Trigger to map the value of the query property inside the data property inside the Trigger data object to $cypher parameter of the receiving Neo4jQuery Function.