mirror of
https://github.com/n8n-io/n8n.git
synced 2025-03-05 20:50:17 -08:00
⚡ Improve how expressions get values
This commit is contained in:
parent
3c819100d8
commit
399397fbb7
|
@ -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.
|
||||
|
|
|
@ -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;
|
||||
```
|
||||
|
||||
|
||||
|
|
|
@ -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(),
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in a new issue