How to Loop using Split In Batches Node

Use Case:

Today’s Date Function will generate the Date and with the help of MySQL Node, I’m getting the email address matching today’s date.

Actually, there are multiple emails, Not only one.

Then Updating the Contact with a Tag in Automizy Node.

The Problem is. It’s updating only the first data got from Database.

I want to loop through this and update all the emails in Automizy which I got from MySQL Node.

Output of MySQL node:

image

Workflow:

Hey @mcnaveen!

The documentation for the Split In Batches node covers what you’re looking for. To give a brief, you have to connect the output of the Automizy node to the input of the Split In Batches node. This way, after the Automizy node gets executed, it will trigger the Split In Batches node. The Split In Batches node will fetch the new batch, pass that information to Automizy. This loop will continue till the Split In Batches node fetches all the information.

Also, you can execute the same workflow without using the Split In Batches node. The Automizy node will update all the emails.

Split in Batches node is a bit confusing for me bro. Do I need to set Batch Size as 1

Why I’m asking this because I can’t predict how much data will come.

How this can be done?

@mcnaveen it makes sense to use the Split In Batches node if you’re not sure about the amount of the data that will be returned. Below is the workflow that might help

Finally got it working & understood.

2 Likes

Hi! I’ve been looking around for answers about executing a workflow over a number of items, and the split in batches node seems to be what my questions are pointing me towards. However, I’m not sure if it works for my use case.

I am trying to develop a workflow where I loop over a fetched result of company names and execute a Uproc process to find an email associated with the company and write that email to the baserow for that company.

Hi @arsalagrey

This is Miquel from uProc. Thank you for using the service.

Your workflow makes sense but must be changed a bit. The usual behaviour is the next one:

  1. Recover companies from Baserow.
  2. Start SplitInBatches (I recommend Batchsize = 1).
  3. Query uProc to get Emails by domain. You need company domain or website. If not available, you need to get domain using one of these tools: “Company/Get company by name” or “Company/Get company domain by name” before.
  4. Set data for updating company in Baserow
  5. Save company
  6. If node: checks if there are more items in your Batch (use noItemsLeft context property). If no more items, finish workflow, otherwise, send flow to SplitInBatches node.

I share modified workflow:

{
  "name": "test_baserow",
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        -700,
        590
      ]
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": "={{$json[\"emailExists\"]}}",
              "value2": "=true"
            }
          ]
        }
      },
      "name": "IF",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        520,
        280
      ]
    },
    {
      "parameters": {
        "keepOnlySet": true,
        "values": {
          "string": [
            {
              "name": "genericEmail",
              "value": "={{$json[\"message\"][\"generic\"]}}"
            },
            {
              "name": "personalEmail",
              "value": "={{$json[\"message\"][\"personal\"]}}"
            },
            {
              "name": "companyId",
              "value": "={{$node[\"Fetch Sponsors Company Rows\"].json[\"results\"][0][\"id\"]}}"
            }
          ],
          "boolean": [
            {
              "name": "emailExists",
              "value": "={{$json[\"result\"]}}"
            }
          ]
        },
        "options": {}
      },
      "name": "Set",
      "type": "n8n-nodes-base.set",
      "typeVersion": 1,
      "position": [
        130,
        590
      ]
    },
    {
      "parameters": {
        "authentication": "headerAuth",
        "url": "=https://api.baserow.io/api/database/rows/table/8732/",
        "options": {},
        "queryParametersUi": {
          "parameter": [
            {
              "name": "filter__field_39738__empty",
              "value": "true"
            },
            {}
          ]
        }
      },
      "name": "Fetch Sponsors Company Rows",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        -510,
        590
      ],
      "credentials": {
        "httpHeaderAuth": "Baserow Org"
      }
    },
    {
      "parameters": {
        "requestMethod": "PATCH",
        "url": "=https://api.baserow.io/api/database/rows/table/8732/{{}}/",
        "options": {},
        "bodyParametersUi": {
          "parameter": [
            {
              "name": "field_39738"
            }
          ]
        }
      },
      "name": "Update Company Baserow With Email",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        360,
        590
      ]
    },
    {
      "parameters": {
        "batchSize": "={{$json[\"count\"]}}",
        "options": {}
      },
      "name": "SplitInBatches",
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 1,
      "position": [
        -260,
        590
      ]
    },
    {
      "parameters": {
        "tool": "getEmailListByDomain",
        "domain": "=warwickesports.com",
        "additionalOptions": {}
      },
      "name": "Get Emails By Domain",
      "type": "n8n-nodes-base.uproc",
      "typeVersion": 1,
      "position": [
        -50,
        590
      ],
      "credentials": {
        "uprocApi": "uProc Prod"
      }
    }
  ],
  "connections": {
    "IF": {
      "main": [
        [],
        [
          {
            "node": "SplitInBatches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set": {
      "main": [
        [
          {
            "node": "Update Company Baserow With Email",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Sponsors Company Rows": {
      "main": [
        [
          {
            "node": "SplitInBatches",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Company Baserow With Email": {
      "main": [
        [
          {
            "node": "IF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SplitInBatches": {
      "main": [
        [
          {
            "node": "Get Emails By Domain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start": {
      "main": [
        [
          {
            "node": "Fetch Sponsors Company Rows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Emails By Domain": {
      "main": [
        [
          {
            "node": "Set",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {},
  "id": "178"
}

Let me know if this works for you or if you have any other doubt.

1 Like

Hi Miquel,

Thank you for your help. It pointed me in the right direction.

I managed to get the scaffolding set up and the base row update working perfectly, however, this workflow only gets executed once for the first item in the batch, and I was wondering how I could have it executed for every single item in the batch.

I greatly appreciate your help!

@arsalagreyt, the split batches node here is not needed. The Uproc node will automatically be executed as many times as inputs it receives. As long, of course, as the data is in a format that n8n understands. If you share the HTTP node response I can help you out to put it together.

 [
{
"count": 136,
"next": "http://api.baserow.io/api/database/rows/table/8860/?=&page=2",
"previous": null,
"results": [
{
"id": 1,
"order": "1.00000000000000000000",
"field_40365": "Creative Tim",
"field_40366": "creative-tim",
"field_40367": "https://www.creative-tim.com",
"field_40368": "creativetim",
"field_40369": "null",
"field_40370": "[email protected]"
},
{
"id": 2,
"order": "2.00000000000000000000",
"field_40365": "French Toasters LLC",
"field_40366": "frenchtoastrllc",
"field_40367": "null",
"field_40368": "FrenchToastrLLC",
"field_40369": "null",
"field_40370": ""
},
{
"id": 3,
"order": "3.00000000000000000000",
"field_40365": "上线了",
"field_40366": "strikingly",
"field_40367": "https://www.sxl.cn/s/careers?ref=wp",
"field_40368": "null",
"field_40369": "null",
"field_40370": ""
},
{
"id": 4,
"order": "4.00000000000000000000",
"field_40365": "Arturia",
"field_40366": "arturia",
"field_40367": "https://www.arturia.com",
"field_40368": "null",
"field_40369": "null",
"field_40370": ""
},
{
"id": 5,
"order": "5.00000000000000000000",
"field_40365": "Shanghai DaoCloud Network Technology Co,. Ltd.",
"field_40366": "shanghai-daocloud-network-technology-co-ltd",
"field_40367": "https://www.daocloud.io?utm_source=vue-sponsor&utm_medium=sponsor&utm_campaign=spo171017&utm_content=vue",
"field_40368": "null",
"field_40369": "null",
"field_40370": ""
},
{
"id": 6,
"order": "6.00000000000000000000",
"field_40365": "Domainr",
"field_40366": "domainr",
"field_40367": "https://domainr.com",
"field_40368": "domainr",
"field_40369": "null",
"field_40370": ""
},
{
"id": 7,
"order": "7.00000000000000000000",
"field_40365": "Kelogs",
"field_40366": "_kelogs",
"field_40367": "https://kelo.gs",
"field_40368": "_kelogs",
"field_40369": "null",
"field_40370": ""
},
{
"id": 8,
"order": "8.00000000000000000000",
"field_40365": "Facebook Open Source",
"field_40366": "fbopensource",
"field_40367": "https://opensource.facebook.com",
"field_40368": "fbOpenSource",
"field_40369": "facebook",
"field_40370": ""
}

There is more in the response, but I thought this much might suffice.

I am confused as to how the uProc Node will keep context of the current item it is iterating over. I was using the currentRunningIndex from the SplitInBatches context.

I don’t think I have my head completely wrapped around how looping or sequential processing of data happens in N8N.

The nodes will automatically do the iteration for you. Your workflow should look as follow.

Can I have a look at the response of the node Fetch Sponsors Company?

Thank you for the help Ricardo. I had earlier posted the wrong response of the HTTP node, but it should be corrected now.

This is my current set up. It only gets executed once.

Check the example below, this a start without knowing what you want to do next.

{
  "nodes": [
    {
      "parameters": {
        "authentication": "headerAuth",
        "url": "=https://mockup-pj5l0yxsjrbr.runkit.sh/",
        "options": {},
        "queryParametersUi": {
          "parameter": [
            {}
          ]
        }
      },
      "name": "Fetch Sponsors Company Rows",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        650,
        300
      ],
      "credentials": {
        "httpHeaderAuth": "asasasasas"
      }
    },
    {
      "parameters": {
        "conditions": {
          "boolean": [
            {
              "value1": true,
              "value2": "={{$node[\"Get Email By Domain\"].json[\"result\"]}}"
            }
          ]
        }
      },
      "name": "Does Company Email Exist",
      "type": "n8n-nodes-base.if",
      "typeVersion": 1,
      "position": [
        1330,
        300
      ]
    },
    {
      "parameters": {
        "tool": "getEmailListInSite",
        "domain": "={{/^(?:[^:]+:\\/\\/(?:[^@\\/?]+@)?([^:\\/?]+))?/.exec($node[\"Fetch Sponsors Company Rows\"].json[\"results\"][0][\"field_40367\"])[1]}}",
        "additionalOptions": {}
      },
      "name": "Get Email By Domain",
      "type": "n8n-nodes-base.uproc",
      "typeVersion": 1,
      "position": [
        1100,
        300
      ],
      "credentials": {
        "uprocApi": "asasasa"
      }
    },
    {
      "parameters": {
        "functionCode": "const results = []\n\nconst data = items[0].json.results\n\nconsole.log(data);\n\nfor (const sponsor of data) {\n    results.push({ json: sponsor })\n}\n\nreturn results;"
      },
      "name": "Function",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        860,
        300
      ]
    }
  ],
  "connections": {
    "Fetch Sponsors Company Rows": {
      "main": [
        [
          {
            "node": "Function",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Email By Domain": {
      "main": [
        [
          {
            "node": "Does Company Email Exist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Function": {
      "main": [
        [
          {
            "node": "Get Email By Domain",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

Hi Ricardo. There may be something I’m getting wrong here. There is still no concept of an iterator that I can use to specify which of the companies in the results I would like to iterate over. In your example, you hardcoded the 0th index.

Do you what to paginate the results of the first HTTP Request? I left it there cuz I was not sure what you wanted to end up doing.

In my example, after I fetch the companies, I would like to execute the workflow from uProc node onwards for every single company returned by the initial HTTP request.

That is exactly what the workflow I sent you is doing.

Is it possible to schedule a quick call to sort this out? I feel like co-op’ing this problem would resolve it rather quickly.

Sure, sent you a private message.