# Join output from two function nodes

**URL:** <https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410>\
**Category:** General\
**Created:** [7 February 2020 20:14 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410 "2020-02-07T20:14:24Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![varun](https://avatars.discourse-cdn.com/v4/letter/v/e9bcb4/32.png) [@varun](https://discourse.nodered.org/u/varun)\
**Post date:** [7 February 2020 20:14 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/1 "2020-02-07T20:14:25Z")

</div>

Hello, I have two separate functions nodes. I want to place the output of both the function nodes in an array. How can I do it? My first function node output contains 5 rows and second function contains one row.

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [7 February 2020 23:23 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/2 "2020-02-07T23:23:42Z")

</div>

Have you looked at the example in the cookbook? [https://cookbook.nodered.org/basic/join-streams](https://cookbook.nodered.org/basic/join-streams)

---

<div class="post-metadata">

**Author:** ![varun](https://avatars.discourse-cdn.com/v4/letter/v/e9bcb4/32.png) [@varun](https://discourse.nodered.org/u/varun)\
**Post date:** [8 February 2020 09:06 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/3 "2020-02-08T09:06:47Z")

</div>

Hello Mr.Zenofmud, thanks for the reply. I did try using the join node and I didnt get the output as expected. My first output has array of 4 elements where each element has content of a 12x36 array. The second output is has element where one element has similar content. Is there any other method that can be used?

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [8 February 2020 10:48 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/4 "2020-02-08T10:48:47Z")

</div>

With out knowing what the data looks like, nor what you are doing in your function nodes or how youset up the join node, I'm making wild guesses.

Can you create a small flow demonstrating the issue? Use two `inject` nodes sending data to your two `function` nodes both connected to the `join` node connected to a `debug` node.

Then you can export the flow and [attach it to a reply](https://discourse.nodered.org/t/how-to-share-code-or-flow-json/506) so I can see what you are actually doing.

---

<div class="post-metadata">

**Author:** ![varun](https://avatars.discourse-cdn.com/v4/letter/v/e9bcb4/32.png) [@varun](https://discourse.nodered.org/u/varun)\
**Post date:** [10 February 2020 19:35 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/5 "2020-02-10T19:35:32Z")

</div>

''''''  
[{"id":"d6473cec.6e153","type":"function","z":"5ae53125.7a892","name":"Calculate average","func":"inputArray = new Array(msg.payload.length);\n//the payload is an array of objects, but an array of arrays is needed. \n//this loop creates an array of arrays for better handling\nfor(var n = 0; n \< inputArray.length; n++){\n inputArray[n] = Object.values(msg.payload[n]);\n}\n\n// Width and height of heating fields in pixels\n// dependant on the distance between camera and object\nconst FIELD\_WIDTH = 50;\nconst FIELD\_HEIGHT = 60;\n\n//WIDTH Resolution of Image\nconst RES\_WIDTH = 640;\n\n// # of heating fields to calculate\nconst FIELDS\_HORIZONTAL = 12; //because of the zig-zag recording of cam 1, to generate same layouts.\nconst FIELDS\_VERTICAL = 36;\n\n// first field starts half the field amount in lenght from the middle of the image\nconst HEATING\_FIELD\_START\_HORIZONTAL = RES\_WIDTH/2 - FIELDS\_HORIZONTAL/2 \* FIELD\_WIDTH;\n\n// Detect start of Fields // empiric values maybe?\nvar HEATING\_FIELD\_START\_DETECTION = detectStartHeating(inputArray);\nvar HEATING\_FIELD\_END\_DETECTION = detectEndHeating(inputArray);\nvar HEATING\_FIELD\_START\_VERTICAL = (HEATING\_FIELD\_END\_DETECTION-HEATING\_FIELD\_START\_DETECTION)/2 + HEATING\_FIELD\_START\_DETECTION - FIELDS\_VERTICAL/2 \* FIELD\_HEIGHT;\n\n\n\n//creating an empty outputArray with the set number of fields\nvar outputArray = new Array(FIELDS\_VERTICAL);\n\nfor(var k = 0; k \< outputArray.length; k++){\n outputArray[k] = new Array(FIELDS\_HORIZONTAL);\n for(var l = 0; l \< outputArray[k].length; l++){\n outputArray[k][l] = 0;\n }\n}\n\nvar tmp2 = 0;\n//loop through the fields\nfor(var v = 0; v \< FIELDS\_VERTICAL; v++){\n for(var h = 0; h \< FIELDS\_HORIZONTAL; h++){\n //calculate the median of each field\n var tmp = 0;\n for(var y = HEATING\_FIELD\_START\_VERTICAL + v \* FIELD\_HEIGHT; y \< HEATING\_FIELD\_START\_VERTICAL + v \* FIELD\_HEIGHT + FIELD\_HEIGHT; y++){\n for(var x = HEATING\_FIELD\_START\_HORIZONTAL + h \* FIELD\_WIDTH; x \< HEATING\_FIELD\_START\_HORIZONTAL + h \* FIELD\_WIDTH + FIELD\_WIDTH; x++){\n //tmp2 = y;\n tmp += parseFloat(inputArray[y]);\n } \n }\n //round to 2 decimals\n tmp = tmp / (FIELD\_WIDTH \* FIELD\_HEIGHT);\n //no decimal digits\n tmp = Math.round(tmp);\n outputArray[v][h] = tmp;\n }\n}\nfunction transpose(a)\n{\n return a && a.length && a[0].map && a[0].map(function (\_, c) { return a.map(function (r) { return r[c]; }); }) || ;\n}\nmsg.payload = transpose(outputArray);\n\nreturn msg;\n\n\nfunction detectStartHeating(inputArray){\n\t//Heat difference from cool row to first heated row, how much hotter does the first heated row have to be?\n\tconst THRESHOLD = 5;\n\n\tvar hotRow = 0;\n\tvar currentRowAverage = calcRowAverage(inputArray, hotRow);\n\thotRow++;\n\tvar nextRowAverage = calcRowAverage(inputArray, hotRow);\n\n\twhile(currentRowAverage + THRESHOLD \> nextRowAverage && currentRowAverage \> -1 && nextRowAverage \> -1){\n\tcurrentRowAverage = nextRowAverage;\n\thotRow++;\n\tnextRowAverage = calcRowAverage(inputArray, hotRow);\n\t}\n\tif(nextRowAverage == -1 || currentRowAverage == -1){\n\t\treturn 0;\n\t}\n\telse{\n\t\treturn hotRow;\n\t}\n}\n\nfunction detectEndHeating(inputArray){\n\t//Heat difference from cool row to first heated row, how much hotter does the first heated row have to be on average?\n\tconst THRESHOLD = 40;\n\n\tvar hotRow = inputArray.length - 1;\n\tvar currentRowAverage = calcRowAverage(inputArray, hotRow);\n\thotRow--;\n\tvar prevRowAverage = calcRowAverage(inputArray, hotRow);\n\t\n\twhile(currentRowAverage + THRESHOLD \> prevRowAverage && currentRowAverage \> -1 && nextRowAverage \> -1 && hotRow \> 0){\n\tcurrentRowAverage = prevRowAverage;\n\thotRow--;\n\tprevRowAverage = calcRowAverage(inputArray, hotRow);\n\t}\n\tif(prevRowAverage == -1 || currentRowAverage == -1){\n\t\treturn 0;\n\t}\n\telse{\n\t\treturn hotRow;\n\t}\n}\n\nfunction calcRowAverage(inputArray, row){\n\tvar res = 0;\n\tif(inputArray.length \< row){\n\t\treturn -1;\n\t}\n\tfor(var g = 0; g \< inputArray[row].length; g++){\n\t\tres += inputArray[row][g];\n\t}\n\treturn res/inputArray[row].length;\n}","outputs":1,"noerr":0,"x":410,"y":240,"wires":[["3aaffd57.fc5732"]]}]

''''''

---

<div class="post-metadata">

**Author:** ![varun](https://avatars.discourse-cdn.com/v4/letter/v/e9bcb4/32.png) [@varun](https://discourse.nodered.org/u/varun)\
**Post date:** [10 February 2020 19:37 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/6 "2020-02-10T19:37:27Z")

</div>

The output of both the nodes should be sent to the ppmp node where i need it. I have attached the file as requested.

---

<div class="post-metadata">

**Author:** ![afelix](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/afelix/32/9743_2.png) [@afelix](https://discourse.nodered.org/u/afelix)\
**Post date:** [10 February 2020 19:40 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/7 "2020-02-10T19:40:30Z")

</div>

Please take a look at the link Paul posted, and edit your post following the instructions there. The forum software mingles posted flows so they can't be properly imported, so it need to be posted in a code block like instructed there.

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [10 February 2020 19:50 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/8 "2020-02-10T19:50:49Z")

</div>

The only thing in this flow is a function node. Where does the join happen?

---

<div class="post-metadata">

**Author:** ![varun](https://avatars.discourse-cdn.com/v4/letter/v/e9bcb4/32.png) [@varun](https://discourse.nodered.org/u/varun)\
**Post date:** [10 February 2020 19:56 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/9 "2020-02-10T19:56:03Z")

</div>

I need the join after the two function nodes. I need the output of both function nodes to used in the PPMP function node.Hence I need to join the output of both functions before sent it to the PPMP function node.When i joined it i was not getting the output as expected.

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [10 February 2020 19:57 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/10 "2020-02-10T19:57:26Z")

</div>

The only thing in the flow you provided is a single function node. No injects, no joins no debug nodes, just a single function node.

Try importing it yourself to see.

---

<div class="post-metadata">

**Author:** ![varun](https://avatars.discourse-cdn.com/v4/letter/v/e9bcb4/32.png) [@varun](https://discourse.nodered.org/u/varun)\
**Post date:** [10 February 2020 20:00 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/11 "2020-02-10T20:00:31Z")

</div>

```auto
[{"id":"b6f81728.0cad78","type":"csv","z":"5ae53125.7a892","name":"ReadCSV","sep":";","hdrin":"","hdrout":"","multi":"mult","ret":"\\n","temp":"","skip":"0","x":260,"y":160,"wires":[["d6473cec.6e153","a2185e9e.b654f"]]},{"id":"7fad285.b9e37d8","type":"inject","z":"5ae53125.7a892","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":40,"wires":[["9b16609e.fe04","3b732271.37f4ae"]]},{"id":"8f85b27d.7ed9","type":"ui_text_input","z":"5ae53125.7a892","name":"FIELD_WIDTH","label":"FIELD_WIDTH","group":"d67bdf37.127d7","order":1,"width":0,"height":0,"passthru":true,"mode":"text","delay":"200","topic":"FIELD_WIDTH","x":100,"y":440,"wires":[["48208b62.02eab4"]]},{"id":"5373abb6.c5aaf4","type":"ui_text_input","z":"5ae53125.7a892","name":"FIELD_HEIGHT","label":"FIELD_HEIGHT","group":"d67bdf37.127d7","order":2,"width":0,"height":0,"passthru":true,"mode":"text","delay":"200","topic":"FIELD_HEIGHT","x":120,"y":500,"wires":[["97e83e14.ab1d6"]]},{"id":"2d6c0be4.078c74","type":"ui_text_input","z":"5ae53125.7a892","name":"FIELD_HORIZONTAL","label":"FIELD_HORIZONTAL","group":"d67bdf37.127d7","order":3,"width":0,"height":0,"passthru":true,"mode":"text","delay":"200","topic":"FIELD_HORIZONTAL","x":140,"y":560,"wires":[["4c067728.5154a8"]]},{"id":"d5e97958.17e288","type":"ui_text_input","z":"5ae53125.7a892","name":"FIELD_VERTICAL","label":"FIELD_VERTICAL","group":"d67bdf37.127d7","order":4,"width":0,"height":0,"passthru":true,"mode":"text","delay":"200","topic":"FIELD_VERTICAL","x":130,"y":620,"wires":[["985cf087.cd4bb"]]},{"id":"48208b62.02eab4","type":"change","z":"5ae53125.7a892","name":"","rules":[{"t":"set","p":"data[\"FIELD_WIDTH\"]","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":440,"wires":[[]]},{"id":"97e83e14.ab1d6","type":"change","z":"5ae53125.7a892","name":"","rules":[{"t":"set","p":"data[\"FIELD_HEIGHT\"]","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":500,"wires":[[]]},{"id":"4c067728.5154a8","type":"change","z":"5ae53125.7a892","name":"","rules":[{"t":"set","p":"data[\"FIELD_HORIZONTAL\"]","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":470,"y":560,"wires":[[]]},{"id":"985cf087.cd4bb","type":"change","z":"5ae53125.7a892","name":"","rules":[{"t":"set","p":"data[\"FIELD_VERTICAL\"]","pt":"flow","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":460,"y":620,"wires":[[]]},{"id":"9b16609e.fe04","type":"ui_button","z":"5ae53125.7a892","name":"CALCULATE","group":"d67bdf37.127d7","order":5,"width":0,"height":0,"passthru":false,"label":"CALCULATE","color":"white","bgcolor":"red","icon":"","payload":"1","payloadType":"str","topic":"","x":130,"y":300,"wires":[[]]},{"id":"3b732271.37f4ae","type":"file in","z":"5ae53125.7a892","name":"","filename":"C:\\Users\\Subhash\\Desktop\\MainHeating_2020-02-06_14-33-38.csv","format":"utf8","chunk":false,"sendError":false,"x":520,"y":40,"wires":[["b6f81728.0cad78"]]},{"id":"d6473cec.6e153","type":"function","z":"5ae53125.7a892","name":"Calculate average","func":"inputArray = new Array(msg.payload.length);\n//the payload is an array of objects, but an array of arrays is needed. \n//this loop creates an array of arrays for better handling\nfor(var n = 0; n < inputArray.length; n++){\n inputArray[n] = Object.values(msg.payload[n]);\n}\n\n// Width and height of heating fields in pixels\n// dependant on the distance between camera and object\nconst FIELD_WIDTH = 50;\nconst FIELD_HEIGHT = 60;\n\n//WIDTH Resolution of Image\nconst RES_WIDTH = 640;\n\n// # of heating fields to calculate\nconst FIELDS_HORIZONTAL = 12; //because of the zig-zag recording of cam 1, to generate same layouts.\nconst FIELDS_VERTICAL = 36;\n\n// first field starts half the field amount in lenght from the middle of the image\nconst HEATING_FIELD_START_HORIZONTAL = RES_WIDTH/2 - FIELDS_HORIZONTAL/2 * FIELD_WIDTH;\n\n// Detect start of Fields // empiric values maybe?\nvar HEATING_FIELD_START_DETECTION = detectStartHeating(inputArray);\nvar HEATING_FIELD_END_DETECTION = detectEndHeating(inputArray);\nvar HEATING_FIELD_START_VERTICAL = (HEATING_FIELD_END_DETECTION-HEATING_FIELD_START_DETECTION)/2 + HEATING_FIELD_START_DETECTION - FIELDS_VERTICAL/2 * FIELD_HEIGHT;\n\n\n\n//creating an empty outputArray with the set number of fields\nvar outputArray = new Array(FIELDS_VERTICAL);\n\nfor(var k = 0; k < outputArray.length; k++){\n outputArray[k] = new Array(FIELDS_HORIZONTAL);\n for(var l = 0; l < outputArray[k].length; l++){\n outputArray[k][l] = 0;\n }\n}\n\nvar tmp2 = 0;\n//loop through the fields\nfor(var v = 0; v < FIELDS_VERTICAL; v++){\n for(var h = 0; h < FIELDS_HORIZONTAL; h++){\n //calculate the median of each field\n var tmp = 0;\n for(var y = HEATING_FIELD_START_VERTICAL + v * FIELD_HEIGHT; y < HEATING_FIELD_START_VERTICAL + v * FIELD_HEIGHT + FIELD_HEIGHT; y++){\n for(var x = HEATING_FIELD_START_HORIZONTAL + h * FIELD_WIDTH; x < HEATING_FIELD_START_HORIZONTAL + h * FIELD_WIDTH + FIELD_WIDTH; x++){\n //tmp2 = y;\n tmp += parseFloat(inputArray[y][x]);\n } \n }\n //round to 2 decimals\n tmp = tmp / (FIELD_WIDTH * FIELD_HEIGHT);\n //no decimal digits\n tmp = Math.round(tmp);\n outputArray[v][h] = tmp;\n }\n}\nfunction transpose(a)\n{\n return a && a.length && a[0].map && a[0].map(function (_, c) { return a.map(function (r) { return r[c]; }); }) || [];\n}\nmsg.payload = transpose(outputArray);\n\nreturn msg;\n\n\nfunction detectStartHeating(inputArray){\n\t//Heat difference from cool row to first heated row, how much hotter does the first heated row have to be?\n\tconst THRESHOLD = 5;\n\n\tvar hotRow = 0;\n\tvar currentRowAverage = calcRowAverage(inputArray, hotRow);\n\thotRow++;\n\tvar nextRowAverage = calcRowAverage(inputArray, hotRow);\n\n\twhile(currentRowAverage + THRESHOLD > nextRowAverage && currentRowAverage > -1 && nextRowAverage > -1){\n\tcurrentRowAverage = nextRowAverage;\n\thotRow++;\n\tnextRowAverage = calcRowAverage(inputArray, hotRow);\n\t}\n\tif(nextRowAverage == -1 || currentRowAverage == -1){\n\t\treturn 0;\n\t}\n\telse{\n\t\treturn hotRow;\n\t}\n}\n\nfunction detectEndHeating(inputArray){\n\t//Heat difference from cool row to first heated row, how much hotter does the first heated row have to be on average?\n\tconst THRESHOLD = 40;\n\n\tvar hotRow = inputArray.length - 1;\n\tvar currentRowAverage = calcRowAverage(inputArray, hotRow);\n\thotRow--;\n\tvar prevRowAverage = calcRowAverage(inputArray, hotRow);\n\t\n\twhile(currentRowAverage + THRESHOLD > prevRowAverage && currentRowAverage > -1 && nextRowAverage > -1 && hotRow > 0){\n\tcurrentRowAverage = prevRowAverage;\n\thotRow--;\n\tprevRowAverage = calcRowAverage(inputArray, hotRow);\n\t}\n\tif(prevRowAverage == -1 || currentRowAverage == -1){\n\t\treturn 0;\n\t}\n\telse{\n\t\treturn hotRow;\n\t}\n}\n\nfunction calcRowAverage(inputArray, row){\n\tvar res = 0;\n\tif(inputArray.length < row){\n\t\treturn -1;\n\t}\n\tfor(var g = 0; g < inputArray[row].length; g++){\n\t\tres += inputArray[row][g];\n\t}\n\treturn res/inputArray[row].length;\n}","outputs":1,"noerr":0,"x":410,"y":240,"wires":[["3aaffd57.fc5732"]]},{"id":"a2185e9e.b654f","type":"function","z":"5ae53125.7a892","name":"Add details","func":"const inputArray = new Array (msg.payload.length);\nfor (var n = 0 ; n < inputArray.length ; n++) {\n inputArray[n] = Object.values(msg.payload[n]);\n}\n\n// width and height of heating fields in pixels\n// dependant on distance between camera and object\n\nconst FIELD_WIDTH = 50;// 4;\nconst FIELD_HEIGHT = 60;// 4;\n\n// Width resolution of Images\n\nconst RES_WIDTH = 640;// 100;\n\n// # of heating fields to calculate\n\nconst FIELDS_HORIZONTAL = 36;// 6;\n\n// because of zig-zag recording of camera 1 to generate same layouts.\n\nconst FIELDS_VERTICAL = 12;// 28;\n\n// first field starts half the field amount in length from middle of the image.\n\nvar HEATING_FIELD_START_HORIZONTAL = RES_WIDTH/2 - FIELDS_HORIZONTAL/2 * FIELD_WIDTH\n\n// Detect start of Fields// emperic values maybe?\n\nvar HEATING_FIELD_START_DETECTION = detectStartHeating(inputArray);\nvar HEATING_FIELD_END_DETECTION = detectEndHeating(inputArray);\nvar HEATING_FIELD_START_VERTICAL = (HEATING_FIELD_END_DETECTION - HEATING_FIELD_START_DETECTION )/ 2 + HEATING_FIELD_START_DETECTION - FIELDS_VERTICAL/2 * FIELD_HEIGHT;\n\n // The positions must be rounded\nHEATING_FIELD_START_HORIZONTAL = Math.round(HEATING_FIELD_START_HORIZONTAL);\nHEATING_FIELD_START_DETECTION = Math.round(HEATING_FIELD_START_DETECTION);\nHEATING_FIELD_END_DETECTION = Math.round(HEATING_FIELD_END_DETECTION);\nHEATING_FIELD_START_VERTICAL = Math.round(HEATING_FIELD_START_VERTICAL);\n// Creating an empty output Array with the set no fields\n\nvar outputArray = new Array (FIELDS_VERTICAL);\nfor (var k = 0 ; k< outputArray.length ; k++) {\n outputArray[k] = new Array (FIELDS_HORIZONTAL);\n for ( var l = 0; l< outputArray[k].length; l++) {\n outputArray[k][l] = 0;\n }\n}\n\nvar tmp2 = 0;\n\n// loop through the fields\n\nfor (var v = 0 ; v < FIELDS_VERTICAL ; v++) {\n for ( var h = 0; h < FIELDS_HORIZONTAL ; h++) {\n \n //calculate median of each field\n var tmp = 0 ;\n for ( var y = HEATING_FIELD_START_VERTICAL + v * FIELD_HEIGHT ; y < HEATING_FIELD_START_VERTICAL + v * FIELD_HEIGHT + FIELD_HEIGHT; y++) {\n for (var x = HEATING_FIELD_START_HORIZONTAL + h * FIELD_WIDTH; x < HEATING_FIELD_START_HORIZONTAL + h * FIELD_WIDTH + FIELD_WIDTH; x++) {\n tmp += parseFloat(inputArray[y][x]);\n }\n }\n \n // round to 2 decimals\n tmp = tmp / (FIELD_WIDTH * FIELD_HEIGHT)\n \n // no of decimal digits\n \n tmp = Math.round(tmp);\n outputArray[v][h] = tmp;\n }\n}\n\n var newOutput = new Array (5);\nfor (var a = 0 ; a< newOutput.length ; a++) {\n // Every row contains as much elements as the total number of fields\n newOutput[a] = new Array (FIELDS_HORIZONTAL * FIELDS_VERTICAL);\n for ( var b = 0; l< newOutput[a].length; b++) {\n newOutput[a][b] = 0;\n }\n}\n\n// Map the current result to the format desired\n// 7 columns were\n// col0 PixelName\n// col1 Width\n// col2 Height\n// col3 X\n// col4 Y\n// col5 Average\n// col6 Consecutive pixel name\n\nlet firstRowIndex = 0;\n for (let rowIndex = 0; rowIndex < outputArray.length; rowIndex++) {\n const row = outputArray[rowIndex];\n for (let colIndex = 0; colIndex < row.length; colIndex++) {\n const col = row[colIndex];\n // Determine the name\n const pixelLetter = getLettherForRowNumber(rowIndex);\n const pixelName = `${pixelLetter}${colIndex + 1}`;\n const X = (colIndex - 18 + 1) * 64 ;\n const Y = getYFromLetter(pixelLetter);\n newOutput[0][firstRowIndex] = pixelName;\n newOutput[1][firstRowIndex] = 64; // Width\n newOutput[2][firstRowIndex] = 100; // Height\n newOutput[3][firstRowIndex] = X; // X\n newOutput[4][firstRowIndex] = Y; // Y\n //newOutput[5] = msg.topic; // Average\n // Determine the name 2\n //const pixelName2 = `a${firstRowIndex}`;\n //newOutput[6][firstRowIndex] = pixelName2;\n firstRowIndex++;\n }\n }\n \n msg.payload = newOutput;\n \n \nreturn msg;\n\n \nfunction detectStartHeating(inputArray) {\n \n // Haet difference from cool row to first heated row, how much hotter does the first heated row to be ?\n \nconst THRESHOLD = 5;\n\nvar hotRow = 0 ;\nvar currentRowAverage = calcRowAverage(inputArray, hotRow);\nhotRow++;\n \nvar nextRowAverage = calcRowAverage(inputArray,hotRow);\nwhile( currentRowAverage + THRESHOLD > nextRowAverage && currentRowAverage > -1 && nextRowAverage > -1) {\n\n currentRowAverage = nextRowAverage;\n hotRow++;\n nextRowAverage = calcRowAverage(inputArray,hotRow);\n}\n if (nextRowAverage == -1 || currentRowAverage == -1) {\n return 0;\n } else {\n return hotRow;\n }\n}\n\nfunction detectEndHeating(inputArray) {\n// heat difference from cool row to first heated row , how much hotter does the first heated row have to on average?\n\n const THRESHOLD = 40;\n var hotRow = inputArray.length - 1;\n var currentRowAverage = calcRowAverage(inputArray, hotRow);\n hotRow--;\n\n var prevRowAverage = calcRowAverage(inputArray,hotRow);\n\n while ( currentRowAverage + THRESHOLD > prevRowAverage && currentRowAverage > -1 && prevRowAverage > -1 && hotRow>0) {\n currentRowAverage = prevRowAverage;\n hotRow--;\n prevRowAverage = calcRowAverage(inputArray,hotRow);\n\n }\n if( prevRowAverage == -2 || currentRowAverage == -1) {\n return 0 ;\n }\n\n else\n {\n return hotRow;\n }\n }\n \nfunction calcRowAverage(inputArray,row) {\n var res = 0;\n if (inputArray.length < row) {\n return -1;\n }\n\n\n for (var g = 0; g< inputArray[row].length; g++) {\n res += inputArray[row][g];\n }\n return res/inputArray[row].length;\n} \n\nfunction getLettherForRowNumber(rowNumber) {\n// ASCII code for 'a' is 97, 122 for 'z'\nif (rowNumber < 26) {\n // Start from 1\n return String.fromCharCode(97 + rowNumber);\n} else {\n const asciiFirstLetter = Math.round(rowNumber / 25) - 1;\n const mod = rowNumber % 25 - 1;\n const firstLetter = String.fromCharCode(97 + asciiFirstLetter);\n const secondLetter = String.fromCharCode(97 + mod);\n return `${firstLetter}${secondLetter}`;\n}\n}\n\nfunction getYFromLetter(letter) {\n const maping = [\n {letter: 'A', value: 600},\n {letter: 'B', value: 500},\n {letter: 'C', value: 400},\n {letter: 'D', value: 300},\n {letter: 'E', value: 200},\n {letter: 'F', value: 100},\n {letter: 'G', value: 0},\n {letter: 'H', value: -100},\n {letter: 'I', value: -200},\n {letter: 'J', value: -300},\n {letter: 'K', value: -400},\n {letter: 'L', value: -500}\n];\n const r = maping.find(obj => obj.letter === letter.toUpperCase());\n return r.value;\n}\n","outputs":1,"noerr":0,"x":450,"y":160,"wires":[["f59ec02.834834"]]},{"id":"487ad679.02a138","type":"function","z":"5ae53125.7a892","name":"PPMP","func":"e = new Date();\n\n\n\n\nvar PPMP = {\n \"content-spec\": \"urn:spec://eclipse.org/unide/measurement-message#v2\",\n \"device\": {\n \"deviceID\": \"418303101\"\n },\n \"part\": {\n \"partTypeID\": msg.partType,\n \"partID\": msg.identifier,\n \"metaData\": {\n \"dsVersion\": \"2.2\",\n \"x_fieldSize\": msg.payload[1],\n \"y_fieldSize\": msg.payload[2],\n \"x_pos_calc\": msg.payload[3],\n \"y_pos_calc\": msg.payload[4]\n }\n },\n \"measurements\": [\n {\n \"ts\": e.toISOString(),\n \"series\": {\n \"$_time\": [\n 0\n],\n \n \"UniqueID\": msg.identifier,\n \"SheetWidth\": msg.SheetWidth,\n \"SheetLength\": msg.SheetLength,\n \"SheetTemp_1\": msg.SheetTemp_1,\n \"SheetTemp_2\": msg.SheetTemp_2,\n \"SheetTemp_3\": msg.SheetTemp_3,\n \"AreaTemp\": msg.AreaTemp,\n \"Name\":msg.payload[0],\n \"Temperature\": msg.topic\n }\n }\n ]\n};\n\nmsg.payload = PPMP;\nreturn msg;","outputs":1,"noerr":0,"x":710,"y":240,"wires":[["9160eef6.72c57"]]},{"id":"9160eef6.72c57","type":"debug","z":"5ae53125.7a892","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":850,"y":240,"wires":[]},{"id":"3aaffd57.fc5732","type":"join","z":"5ae53125.7a892","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":570,"y":280,"wires":[["80de3e96.e77c3"]]},{"id":"f59ec02.834834","type":"join","z":"5ae53125.7a892","name":"","mode":"auto","build":"string","property":"payload","propertyType":"msg","key":"topic","joiner":"\\n","joinerType":"str","accumulate":"false","timeout":"","count":"","reduceRight":false,"x":600,"y":160,"wires":[["264a51e4.18ec4e"]]},{"id":"264a51e4.18ec4e","type":"debug","z":"5ae53125.7a892","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":780,"y":160,"wires":[]},{"id":"80de3e96.e77c3","type":"debug","z":"5ae53125.7a892","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":750,"y":340,"wires":[]},{"id":"d67bdf37.127d7","type":"ui_group","z":"","name":"control","tab":"f362086e.49c898","order":1,"disp":true,"width":"6","collapse":false},{"id":"f362086e.49c898","type":"ui_tab","z":"","name":"Home","icon":"dashboard"}]

```

---

<div class="post-metadata">

**Author:** ![varun](https://avatars.discourse-cdn.com/v4/letter/v/e9bcb4/32.png) [@varun](https://discourse.nodered.org/u/varun)\
**Post date:** [10 February 2020 20:01 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/12 "2020-02-10T20:01:19Z")

</div>

Sorry Sir. I have attached the flow properly now. I included two join node as you suggested.

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [10 February 2020 20:18 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/13 "2020-02-10T20:18:55Z")

</div>

Looking at your flow, it is clear to me that you haqve not looked at the example in the cookbook I pointed you at in my first reply. Please go import that flow and read the documentation and then I think you should be able to see ywhy your `join` node`s` are not working.

---

<div class="post-metadata">

**Author:** ![varun](https://avatars.discourse-cdn.com/v4/letter/v/e9bcb4/32.png) [@varun](https://discourse.nodered.org/u/varun)\
**Post date:** [10 February 2020 20:38 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/14 "2020-02-10T20:38:38Z")

</div>

I did see that example and even tried it by combining each payload to form an array. But the array was not giving the desired output.

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [10 February 2020 21:03 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/15 "2020-02-10T21:03:08Z")

</div>

You need to play with the join node and see how it works. If you have one msg with an array of 3 times and you join it to another msg that contains an array of 2 items, you will NOT end up with an array of 5 items but two arrays - one with 3 items and one with 2 items. After that you can combine them into one array eithor via a function node or a change node using jsonata

---

<div class="post-metadata">

**Author:** ![varun](https://avatars.discourse-cdn.com/v4/letter/v/e9bcb4/32.png) [@varun](https://discourse.nodered.org/u/varun)\
**Post date:** [10 February 2020 21:10 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/16 "2020-02-10T21:10:19Z")

</div>

Okay Sir. Will try that.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [10 April 2020 21:10 UTC](https://discourse.nodered.org/t/join-output-from-two-function-nodes/21410/17 "2020-04-10T21:10:25Z")

</div>

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.
