Function for multiple items

Hi everyone,

I can’t figure out how to run a Function on multiple items.
I’m looping through items[0].json, however there is an items[1].json, items[2].json, etc, and I’m not sure what to do other than copy the same Function multiple times. (Which is not a good solution, as the number of items might change.

If I map the items into one item, that just causes more headache later in the workflow as I can’ figure otu how to get all of the data out of it as needed, so I would prefer to take care of the problem here.

Thanks for any help

(part of) my workflow, with some mock data:

{
  "nodes": [
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "name",
              "value": "={{$node[\"Function\"].json[\"tokenInfo\"][\"name\"]}}"
            },
            {
              "name": "symbol",
              "value": "={{$node[\"Function\"].json[\"tokenInfo\"][\"symbol\"]}}"
            },
            {
              "name": "coingecko",
              "value": "={{$node[\"Function\"].json[\"tokenInfo\"][\"coingecko\"]}}"
            },
            {
              "name": "address",
              "value": "={{$node[\"ETHPlorer API\"].json[\"data\"][\"address\"]}}"
            }
          ],
          "number": [
            {
              "name": "decimals",
              "value": "={{$node[\"Function\"].json[\"tokenInfo\"][\"decimals\"]}}"
            },
            {
              "name": "rawbalance",
              "value": "={{$node[\"Function\"].json[\"rawBalance\"]}}"
            },
            {
              "name": "balance",
              "value": "={{$node[\"Function\"].json[\"rawBalance\"] / (10**$json[\"tokenInfo\"][\"decimals\"])}}"
            }
          ]
        },
        "options": {}
      },
      "name": "Set3",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        1146,
        423
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "address",
              "value": "=0x85c472b13c20460D44aEC35346f3441959F6Dd33"
            }
          ],
          "boolean": []
        },
        "options": {}
      },
      "name": "Set",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        526,
        393
      ]
    },
    {
      "parameters": {
        "values": {
          "string": [
            {
              "name": "address",
              "value": "=0xeEF199152838F08406E17776487fa661696F2a88"
            }
          ],
          "boolean": []
        },
        "options": {}
      },
      "name": "Set2",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        526,
        523
      ]
    },
    {
      "parameters": {},
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 1,
      "position": [
        706,
        443
      ]
    },
    {
      "parameters": {
        "url": "=http://api.ethplorer.io/getAddressInfo/{{$json[\"address\"]}}",
        "options": {
          "batchInterval": 500
        },
        "headerParametersUi": {
          "parameter": []
        },
        "queryParametersUi": {
          "parameter": [
            {
              "name": "apiKey",
              "value": "freekey"
            }
          ]
        }
      },
      "name": "ETHPlorer API",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        856,
        433
      ],
      "alwaysOutputData": false
    },
    {
      "parameters": {
        "functionCode": "const result = []\n\nconst lineItems = items[0].json.tokens\n\nfor (const lineItem of lineItems) {\n   result.push({ json: lineItem })\n}\n\nreturn result;\n\n\n"
      },
      "name": "Function",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        1006,
        423
      ]
    }
  ],
  "connections": {
    "Set": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set2": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "ETHPlorer API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ETHPlorer API": {
      "main": [
        [
          {
            "node": "Function",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function": {
      "main": [
        [
          {
            "node": "Set3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Welcome to the community @telos

Change the function node to the code below. That should do it.

const results = []

for (const item of items) {
  for (const token of item.json.tokens) {
    results.push({ json: token })
  }
}

return results;

I just knew that the answer will be making me feel stupid for overlooking it.
I was half right. I actually previously tried using the same code you suggested, however it didn’t work (ERROR: item.json.tokens is not iterable - and really didn’t understand why so I moved on).

But now that I tried it with my example workflow, it worked flawlessly so I looked into it, and manage to figure out the reason: one of the addresses I query (that it not in the example that I provided) doesn’t have a “tokens” object.

Now I just have to figure out how to exclude responses that has no tokens object. Probably an IF node, but I leave it for tomorrow.

Thank you very much for the help and the welcome.

You can add an if before the loop. Check the example below.

const results = []

for (const item of items) {
  if (item.json.hasOwnProperty('tokens')) {
      for (const token of item.json.tokens) {
      results.push({ json: token })
    }
  }
}

return results;
1 Like

Thanks again.
I was trying to avoid turning this into a javascript helpdesk, but one additional question.

I need to add the ETH address value to every one of the tokenInfo strings, but just can’t figure out how.
Every item has a different ETH address to add.

So I’m looking from this:

 [
{
"address": "0x85c472b13c20460d44aec35346f3441959f6dd33",
"ETH": {
"price": {
"rate": 3195.1098860615193,
"diff": -6.87,
"diff7d": -19.16,
"ts": 1631531762,
"marketCapUsd": 375442502251.81396,
"availableSupply": 117505348.999,
"volume24h": 17305270902.642925,
"diff30d": -3.005162245409764,
"volDiff1": -2.727215391286208,
"volDiff7": 8.460140704535405,
"volDiff30": 0.7670256816714414
},
"balance": 7.214738026712414,
"rawBalance": "7214738026712414138"
},
"countTxs": 316,
"tokens": [
{
"tokenInfo": {
"address": "0x0e49144b8b8d228eb7d266f15b2e140fea72a54e",
"decimals": "0",
"name": "Abstract Store",
"owner": "0x",
"symbol": "DAVIS",
"totalSupply": "100",
"lastUpdated": 1628121185,
"issuancesCount": 0,
"holdersCount": 1,
"ethTransfersCount": 0,
"price": false
},
"balance": 1,
"totalIn": 0,
"totalOut": 0,
"rawBalance": "1"
},

To this, for every single one of the tokenInfo strings in the item(s):

 [
{
"address": "0x85c472b13c20460d44aec35346f3441959f6dd33",
"ETH": {
"price": {
"rate": 3195.1098860615193,
"diff": -6.87,
"diff7d": -19.16,
"ts": 1631531762,
"marketCapUsd": 375442502251.81396,
"availableSupply": 117505348.999,
"volume24h": 17305270902.642925,
"diff30d": -3.005162245409764,
"volDiff1": -2.727215391286208,
"volDiff7": 8.460140704535405,
"volDiff30": 0.7670256816714414
},
"balance": 7.214738026712414,
"rawBalance": "7214738026712414138"
},
"countTxs": 316,
"tokens": [
{
"tokenInfo": {
"ETHaddress": "0x85c472b13c20460d44aec35346f3441959f6dd33",
"address": "0x0e49144b8b8d228eb7d266f15b2e140fea72a54e",
"decimals": "0",
"name": "Abstract Store",
"owner": "0x",
"symbol": "DAVIS",
"totalSupply": "100",
"lastUpdated": 1628121185,
"issuancesCount": 0,
"holdersCount": 1,
"ethTransfersCount": 0,
"price": false
},
"balance": 1,
"totalIn": 0,
"totalOut": 0,
"rawBalance": "1"
},

Hey @telos,

I’ve modified the solution that Ricardo provided. This new solution will add the ETH address to the tokenInfo object.

const results = []

for (const item of items) {
  if (item.json.hasOwnProperty('tokens')) {
      for (const token of item.json.tokens) {
      const ETHaddress = {ETHaddress:item.json.address};
      Object.assign(token.tokenInfo, ETHaddress);
      results.push({ json: token })
    }
  }
}

return results;

Hey, @harshil1712

Looks good, thank you.

1 Like