Looping binary data in function node

Hello ,
I use http request node to obtain 2 jpg file , (namely (1) data and (2) data ) and merge with json key using merge node as shown below.

after which , I update the file to lark api to obtain image key as shown below with following code

const request = require('request-promise-native');   //need to reinstall n8n with variable here to use it
const x = items[0].json.key  //obtain authorization key
const binaryData = items[1].binary.data;      //name of file is called "data under items"
const metadata = {
  name : binaryData.fileName,
}
const options = {
  uri: 'https://open.larksuite.com/open-apis/image/v4/put/',    //url to send http post
  headers: {
    'content-type': 'multipart/form-data',
    'Authorization' : `Bearer ${x}`,
  },

  formData: {
    image: {
      value: Buffer.from(binaryData.data, 'base64'),
      options: {
	    filename: binaryData.fileName,
	  },
 	},

    image_type: "message"    // json to appear in the body.
  },

  method: 'POST',     
}

const response = await request(options);

return [{ json: {response} }]   //display respond from http request in json. 

Currently, if i want to upload 1st data file, i will use the following code

const binaryData = items[1].binary.data;

while if i want to upload 2nd data file, i will use the following code

const binaryData = items[2].binary.data;

May i know if there is anyway i could loop the file upload process so that i could return a few image key in a single execution ?

the number of file obtain from http request will depends on number of files upload by user, therefore, in certain uploads, it might be more than 2 , while in certain upload , it might be a single file.

Hi @Benjamin123, items is a 0-based array of all items and available inside the Function node.

So in case you just want to loop through multiple items in your code, starting from the second item (item[1]) onwards, you can use a simple JS loop like so:

 for (let i = 1; i < items.length; i++) {
  // Looped code goes here
} 
Example Workflow
{
  "nodes": [
    {
      "parameters": {},
      "name": "Start",
      "type": "n8n-nodes-base.start",
      "typeVersion": 1,
      "position": [
        240,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "const urls = [\n  'https://unsplash.com/photos/hcrmrVVdwqI/download?ixid=MnwxMjA3fDB8MXxhbGx8NXx8fHx8fDJ8fDE2Mzk2NDE2MTA&force=true&w=640',\n  'https://unsplash.com/photos/IRNjU79Es6k/download?ixid=MnwxMjA3fDB8MXxhbGx8Mnx8fHx8fDJ8fDE2Mzk2NDE2MTA&force=true&w=640',\n  'https://unsplash.com/photos/h74VKnNUiAE/download?ixid=MnwxMjA3fDB8MXxhbGx8OHx8fHx8fDJ8fDE2Mzk2NDE2MTA&force=true&w=640'\n];\n\nreturn urls.map(e => { return {\n    json: {\n      url: e\n    }\n  }\n});"
      },
      "name": "Set Download URLs",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        460,
        300
      ]
    },
    {
      "parameters": {
        "url": "={{$json[\"url\"]}}",
        "responseFormat": "file",
        "options": {}
      },
      "name": "Download Files",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 1,
      "position": [
        680,
        300
      ]
    },
    {
      "parameters": {
        "functionCode": "const request = require('request-promise-native');\nlet responses = [];\n\nfor (let i = 1; i < items.length; i++) {\n  const binaryData = items[i].binary.data;\n  const metadata = {\n  name : binaryData.fileName,\n  }\n  const options = {\n  uri: 'https://hookb.in/eKN87PO7amHlwQmmwRGy',  //url to send http post\n  headers: {\n    'content-type': 'multipart/form-data'\n  },\n\n  formData: {\n    image: {\n    value: Buffer.from(binaryData.data, 'base64'),\n    options: {\n      filename: binaryData.fileName,\n    },\n    },\n\n    image_type: \"message\"  // json to appear in the body.\n  },\n\n  method: 'POST',   \n  }\n\n  const response = await request(options);\n  responses.push({\n    json: {\n      response: response\n    }\n  })\n} \n\nreturn responses;\n"
      },
      "name": "Loop Binary Data",
      "type": "n8n-nodes-base.function",
      "typeVersion": 1,
      "position": [
        900,
        300
      ]
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Set Download URLs",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Download URLs": {
      "main": [
        [
          {
            "node": "Download Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Files": {
      "main": [
        [
          {
            "node": "Loop Binary Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

In this example workflow, I’m downloading three files and then upload the later two. It should also work for different numbers of files. Hope this helps!

@MutedJam thank you very much. I am getting 2 response now… :grinning:

1 Like