Function Node: How can I use an expression for the iterable variable as part of a FOR/Of loop to access a certain key value at runtime

Hi n8n,

I am trying to work out the syntax for a javascript function problem.

My input data to the function node has an array key that changes depending on the results of an earlier query.

Example:
Query 1 results:

{
"data": {
"tla_master": [
{
"ent_tla": "ENT IGNORE",
"model": null,
"manufacturer": null,
"discipline": "value not set",
"description": "HMC SMARTSHEET FORMULA ROW"
 }]
 }

The data part is consistent, but the “tla_master” key can change. Next time the query is run, it might be “8100_cables” for example.

The function node that I am deploying is extracting the data out of the array under data.tla_master, to make it a simple list of non-nested items for further processing.

The key FOR/OF statement in my function node looks like this:

const newItems = [];

for (const element of items[0].json.data.tla_master) {
   newItems.push({json:element});
}

return newItems;

My problem is that the tla_master portion of this for/of loop needs to change if the array key changes. Now, I know what this value is from elsewhere (another node).

so my question is, is there a way to use a variable/expression in the for/of statement to fill in that part of the object name?

items[0].json.data.VARIABLE_HERE

Here’s the copy/paste of the function node:

{
“nodes”: [
{
“parameters”: {
“functionCode”: “const newItems = [];\n\nfor (const element of items[0].json.data.tla_master) {\n newItems.push({json:element});\n}\n\nreturn newItems;\n”
},
“name”: “Flatten JSON”,
“type”: “n8n-nodes-base.function”,
“typeVersion”: 1,
“position”: [
470,
470
]
}
],
“connections”: {}
}

Thanks in advance for this.

Additional Edit:

Looking at a post, i think there is something along these lines to achieve what I want, but I can’t make it work in the for/of statement (probably my skills, not n8n/JS)
Adding expressions inside functions

items[0].json.myVariable = $node["RSS Feed Reader"].parameter["url"];
return items;

In my case, I THINK the variable assignment would look like this as it’s not a parameter but part of the JSON output:

items[0].json.myVariable = $node["Common Start"].json["dataItemKey"];

Now using that variable inside the for/of loop is where it seems to fail.

Also, there may be a better way to pull this array out to items than a function loop…

I thought maybe the Item Lists node could do it, but I can’t figure out how to grab a nested field for the “field to split out”. Maybe if I use function item first to get rid of the data key?

–Additional Info–
Used the function item node to strip “data”:

{
  "nodes": [
    {
      "parameters": {
        "functionCode": "// Code here will run once per input item.\n// More info and help: https://docs.n8n.io/nodes/n8n-nodes-base.functionItem\n\n// Add a new field called 'myNewField' to the JSON of the item\nitem = item.data;\n\nreturn item;"
      },
      "name": "FunctionItem",
      "type": "n8n-nodes-base.functionItem",
      "typeVersion": 1,
      "position": [
        470,
        310
      ]
    }
  ],
  "connections": {}
}

Now all I need is how to use a variable in this function item:
I need item.$key or something instead of item.tla_master…

let key = $node["Common Start"].json["dataItemKey"];

item = item.tla_master;

return item;

So Close!
The challenge here is that “dataItemKey” is not the object, its the string value of the key value of the object…

Do not think you need to know the name of the key to extracting the data within the array for further processing. As long as there is only one key there, Object.keys() should do it. Check the function node and the test workflow below

const data = items[0].json.data
const key = Object.keys(data)[0]
return data[key].map(d => ({ json: d }))
Example workflow
{
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        250,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "const random = Math.floor(Math.random() * 2);\n\nlet response;\n\nif (random === 1) {\n  response =   {\n   \"data\":{\n      \"tla_master\":[\n         {\n            \"ent_tla\":\"ENT IGNORE\",\n            \"model\":null,\n            \"manufacturer\":null,\n            \"discipline\":\"value not set\",\n            \"description\":\"HMC SMARTSHEET FORMULA ROW\"\n         }\n      ]\n   }\n }\n \n} else {\n  response = {\n   \"data\":{\n      \"8100_cables\":[\n         {\n            \"ent_tla\":\"ENT IGNORE2\",\n            \"model\":null,\n            \"manufacturer\":null,\n            \"discipline\":\"value not set\",\n            \"description\":\"HMC SMARTSHEET FORMULA ROW\"\n         }\n      ]\n   }\n}\n}\n\nreturn [\n  {\n    json: response\n  }\n]"
      },
      "name": "Function",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        530,
        300
      ],
      "notesInFlow": true,
      "notes": "Mockup data"
    },
    {
      "parameters": {
        "functionCode": "const data = items[0].json.data\nconst key = Object.keys(data)[0]\nreturn data[key].map(d => ({ json: d }))\n"
      },
      "name": "Function1",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        750,
        300
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Function",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function": {
      "main": [
        [
          {
            "node": "Function1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}