Refer a state from node

Hi,
I am new and still trying to learn n8n as much as I can. I got some basic questions on state management.

I have a workflow where I got a list of project ids and will loop through each item via RestAPI to query the events. It works well.

Until now I need to add an extra parameter to the RestAPI call for a time range.
I have created a new function node and I can output the correct time range.

The issue is how I can reference this time range correctly in the RestAPI node?
I cannot connect the function node that output the time range directly to it since it is not the input data(input data is the project ids). This is merely an extra parameter to the node.

And if I just reference the node name, seems that I get not found issue.

Here is a screen shot. So basically I need to reference the CapTime in GetEventForEachProject node without connecting it. And also need to make sure the CapTime function has run before the GetEventForEachProject.

Hey @David_Liu welcome to our community forums!

There are a few ways you can do it. The “Extract project IDs” node could output an entirely new collection where you are only using the IDs and Dates as output. This would allow you to use them in expressions.

Also, while building a workflow you can click the “Execute Node” button that executes a single node (or all its predecessors, if there are any) so you can get a preview of their output data.

This allows you to reference this data in future nodes using the node name. Let me show you an example in the workflow below (you can copy this JSON and paste to your n8n instance):

{
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "url": "https://jsonplaceholder.typicode.com/users",
        "options": {
          "splitIntoItems": true
        }
      },
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        450,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "const newOutput = [];\nfor (item of items) {\n  newOutput.push({\n    json: {\n      id: item.json.id,\n      startDate: new Date().toISOString()\n    }\n  });\n}\n\nreturn newOutput;"
      },
      "name": "Function",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        650,
        300
      ]
    },
    {
      "parameters": {
        "url": "=https://jsonplaceholder.typicode.com/users/{{$node[\"HTTP Request\"].json[\"id\"]}}?startDate={{$json[\"startDate\"]}}",
        "options": {}
      },
      "name": "HTTP Request1",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        850,
        300
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "HTTP Request",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "main": [
        [
          {
            "node": "Function",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function": {
      "main": [
        [
          {
            "node": "HTTP Request1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Please note: The output of the function node is a new collection of elements, containing only the ID and date. This could be a solution. Also, I am referencing the ID field from the HTTP Request node and not from the direct input, as you can see in the second HTTP Request node.

I hope this clarifies a few ways to do it =)

Hi @krynble,

Thanks for your quick help.

It is true that we can aggregate the start date into the data itself. And thanks for showing me the example of doing that.

Just it feels less efficient overall. For example, if we wanted to inject a very large json data, then it will be carried forward to each item which wastes a lot of space.

Wondering why every node does not have a side chain inlet, to which other nodes can connects. These side chain inlets are only for node dependency which ensures proper node execution without actually passing the data as outputs, and in this way expressions can work properly for node output data?

Or is there any space efficient way that is better than appending this to every item?

Hey @David_Liu!

Welcome to the community :sparkling_heart:

An alternate approach would be to write the code snippet in the Expression Editor, instead of using the Function node. However, this would only work when using default JS functions and methods. This won’t work if you’re defining variables, running loops, creating functions.

Here’s the modified HTTP Request from the example shared by Omar,

{
  "nodes": [
    {
      "parameters": {
        "url": "=https://jsonplaceholder.typicode.com/users/{{$node[\"HTTP Request\"].json[\"id\"]}}?startDate={{new Date().toISOString()}}",
        "options": {}
      },
      "name": "HTTP Request1",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        1010,
        280
      ]
    }
  ],
  "connections": {}
}
1 Like

If you care only about execution order and reference data you can use the Merge-Node with the “Mode” set to “Wait” or “Pass-through”. It will then wait until both input nodes did run. You can then reference the value normally.

2 Likes