Improve how expressions get values

This commit is contained in:
Jan Oberhauser 2020-04-13 15:57:01 +02:00
parent 3c819100d8
commit 399397fbb7
3 changed files with 67 additions and 13 deletions

View file

@ -52,8 +52,9 @@ The following special variables are available:
- **$env**: Environment variables
- **$items**: Environment variables
- **$json**: Incoming JSON data of a node
- **$node**: Data of other nodes (context, output-data, parameters)
- **$node**: Data of other nodes (binary, context, json, parameter, runIndex)
- **$parameters**: Parameters of the current node
- **$runIndex**: The current run index (first time node gets executed it is 0, second time 1, ...)
- **$workflow**: Returns workflow metadata like: active, id, name
Normally it is not needed to write the JavaScript variables manually as they can be simply selected with the help of the Expression Editor.

View file

@ -59,7 +59,7 @@ return newItems;
```
#### Method: $item(index: number)
#### Method: $item(index: number, runIndex?: number)
With `$item` it is possible to access the data of parent nodes. That can be the item data but also
the parameters. It expects as input an index of the item the data should be returned for. This is
@ -71,6 +71,12 @@ emails at once to different people. Instead, the same person would receive multi
The index is 0 based. So `$item(0)` will return the first item, `$item(1)` the second one, ...
By default will the item of the last run of the node be returned. So if the referenced node did run
3x (its last runIndex is 2) and the current node runs the first time (its runIndex is 0) will the
data of runIndex 2 of the referenced node be returned.
For more information about what data can be accessed via $node check [here](#variable-node).
Example:
```typescript
@ -92,9 +98,9 @@ const channel = $item(9).$node["Slack"].parameter["channel"];
Gives access to all the items of current or parent nodes. If no parameters get supplied
it returns all the items of the current node.
If a node-name is given, it returns the items the give node did output. By default of the
first output (index: 0, most nodes only have one output, exceptions are IF and Switch-Node)
and the current run.
If a node-name is given, it returns the items the node did output on it`s first output
(index: 0, most nodes only have one output, exceptions are IF and Switch-Node) on
its last run.
Example:
@ -102,22 +108,58 @@ Example:
// Returns all the items of the current node and current run
const allItems = $items();
// Returns all items the node "IF" outputs (index: 0 which is Output "true" of current run)
// Returns all items the node "IF" outputs (index: 0 which is Output "true" of its most recent run)
const allItems = $items("IF");
// Returns all items the node "IF" outputs (index: 1 which is Output "false" of run 0 which is the first one)
// Returns all items the node "IF" outputs (index: 0 which is Output "true" of the same run as current node)
const allItems = $items("IF", 0, $runIndex);
// Returns all items the node "IF" outputs (index: 1 which is Output "false" of run 0 which is the first run)
const allItems = $items("IF", 1, 0);
```
#### Variable: $node
Works exactly like `$item` with the difference that it will always return the data of the first item.
Works exactly like `$item` with the difference that it will always return the data of the first item and
the last run of the node.
```typescript
// Returns the fileName of binary property "data" of Node "HTTP Request"
const fileName = $node["HTTP Request"].binary["data"]["fileName"]}}
// Returns the context data "noItemsLeft" of Node "SplitInBatches"
const noItemsLeft = $node["SplitInBatches"].context["noItemsLeft"];
// Returns the value of the JSON data property "myNumber" of Node "Set"
const myNumber = $node["Set"].json['myNumber'];
// Returns the value of the parameter "channel" of Node "Slack"
const channel = $node["Slack"].parameter["channel"];
// Returns the index of the last run of Node "HTTP Request"
const runIndex = $node["HTTP Request"].runIndex}}
```
#### Variable: $runIndex
Contains the index of the current run of the node.
```typescript
// Returns all items the node "IF" outputs (index: 0 which is Output "true" of the same run as current node)
const allItems = $items("IF", 0, $runIndex);
```
#### Variable: $workflow
Gives information about the current workflow.
```typescript
const isActive = $workflow.active;
const workflowId = $workflow.id;
const workflowName = $workflow.name;
```

View file

@ -12,6 +12,7 @@ import {
export class WorkflowDataProxy {
private workflow: Workflow;
private runExecutionData: IRunExecutionData | null;
private defaultReturnRunIndex: number;
private runIndex: number;
private itemIndex: number;
private activeNodeName: string;
@ -19,9 +20,10 @@ export class WorkflowDataProxy {
constructor(workflow: Workflow, runExecutionData: IRunExecutionData | null, runIndex: number, itemIndex: number, activeNodeName: string, connectionInputData: INodeExecutionData[]) {
constructor(workflow: Workflow, runExecutionData: IRunExecutionData | null, runIndex: number, itemIndex: number, activeNodeName: string, connectionInputData: INodeExecutionData[], defaultReturnRunIndex = -1) {
this.workflow = workflow;
this.runExecutionData = runExecutionData;
this.defaultReturnRunIndex = defaultReturnRunIndex;
this.runIndex = runIndex;
this.itemIndex = itemIndex;
this.activeNodeName = activeNodeName;
@ -130,7 +132,8 @@ export class WorkflowDataProxy {
throw new Error(`No execution data found for node "${nodeName}"`);
}
runIndex = runIndex === undefined ? that.runIndex : runIndex;
runIndex = runIndex === undefined ? that.defaultReturnRunIndex : runIndex;
runIndex = runIndex === -1 ? (that.runExecutionData.resultData.runData[nodeName].length -1) : runIndex;
if (that.runExecutionData.resultData.runData[nodeName].length < runIndex) {
throw new Error(`No execution data found for run "${runIndex}" of node "${nodeName}"`);
@ -201,7 +204,7 @@ export class WorkflowDataProxy {
name = name.toString();
if (['binary', 'data', 'json'].includes(name)) {
const executionData = that.getNodeExecutionData(nodeName, shortSyntax);
const executionData = that.getNodeExecutionData(nodeName, shortSyntax, undefined);
if (executionData.length <= that.itemIndex) {
throw new Error(`No data found for item-index: "${that.itemIndex}"`);
@ -241,6 +244,11 @@ export class WorkflowDataProxy {
} else if (name === 'parameter') {
// Get node parameter data
return that.nodeParameterGetter(nodeName);
} else if (name === 'runIndex') {
if (that.runExecutionData === null || !that.runExecutionData.resultData.runData[nodeName]) {
return -1;
}
return that.runExecutionData.resultData.runData[nodeName].length - 1;
}
return Reflect.get(target, name, receiver);
@ -328,8 +336,9 @@ export class WorkflowDataProxy {
$data: {}, // Placeholder
$env: this.envGetter(),
$evaluateExpression: (expression: string) => { }, // Placeholder
$item: (itemIndex: number) => {
const dataProxy = new WorkflowDataProxy(this.workflow, this.runExecutionData, this.runIndex, itemIndex, this.activeNodeName, this.connectionInputData);
$item: (itemIndex: number, runIndex?: number) => {
const defaultReturnRunIndex = runIndex === undefined ? -1 : runIndex;
const dataProxy = new WorkflowDataProxy(this.workflow, this.runExecutionData, this.runIndex, itemIndex, this.activeNodeName, this.connectionInputData, defaultReturnRunIndex);
return dataProxy.getDataProxy();
},
$items: (nodeName?: string, outputIndex?: number, runIndex?: number) => {
@ -339,6 +348,7 @@ export class WorkflowDataProxy {
executionData = that.connectionInputData;
} else {
outputIndex = outputIndex || 0;
runIndex = runIndex === undefined ? -1 : runIndex;
executionData = that.getNodeExecutionData(nodeName, false, outputIndex, runIndex);
}
@ -347,6 +357,7 @@ export class WorkflowDataProxy {
$json: {}, // Placeholder
$node: this.nodeGetter(),
$parameter: this.nodeParameterGetter(this.activeNodeName),
$runIndex: this.runIndex,
$workflow: this.workflowGetter(),
};