Subflow 2 Module helper flow

Hey y'all

In the last month, I have seen a slight increase in the need to package subflows as modules,
and the guide to do that is here : Packaging a Subflow as a module : Node-RED.

This is currently a manual affair.
And one of the time consuming parts, is to manually make changes to the export of the subflow.

This small, no-fuss flow, should help address that!

Simply, paste your subflow export (please see guide, and I suggested using the formatted option) into the Paste JSON In Here template node, and click Generate.

The debug will then print the output that needs to be used in the subflow.json file (as explained in the guide linked above)

Anyway, it's just a thing I quickly put together, but should do the trick.
Please note: This was created (and tested) in Node RED 3.1.0, so just a reminder, it might not be compatible with earlier versions :man_shrugging:

Enjoy & Happy Friday

[{"id":"b7329b63e35ef370","type":"tab","label":"Subflow To Module Helper","disabled":false,"info":"","env":[]},{"id":"5ad4c1667cdee07f","type":"inject","z":"b7329b63e35ef370","name":"Generate","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":200,"y":145,"wires":[["8289fb654090dedd"]]},{"id":"0c8644b1b01426f4","type":"function","z":"b7329b63e35ef370","name":"Fix me up baby!","func":"let parsedObject = msg.payload\n\nparsedObject = parsedObject.filter((n) => !n.type.startsWith(\"subflow:\"))\n\nconst nodes = parsedObject.filter((n) => n.type !== 'subflow')\nconst subflow = parsedObject.filter((n) => n.type === 'subflow')[0]\n\nmsg.payload  = {\n    ...subflow,\n    flow:[...nodes]\n}\n\nreturn msg","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":215,"y":275,"wires":[["469ac5aae85ef83f"]]},{"id":"8289fb654090dedd","type":"template","z":"b7329b63e35ef370","name":"Paste JSON In Here","field":"payload","fieldType":"msg","format":"json","syntax":"plain","template":"","output":"json","x":225,"y":210,"wires":[["0c8644b1b01426f4"]]},{"id":"469ac5aae85ef83f","type":"debug","z":"b7329b63e35ef370","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":445,"y":275,"wires":[]}]

2024-04-09 Flow updated as described in post #7

5 Likes

Thank for this Marcus. Very useful.

1 Like

Anytime!

It should still be current (hopefully) - was tested of course in 3.1

Yes, it is working well with 4.0.0 Beta 1.
By adding a JSON node with Format JSON String selected and a file out node then it can generate the subflow.json file directly.

1 Like

@marcus-j-davies note there is a nasty issue which I am sure is an oversight - must admit it took me a bit to figure out what it was ! nothing to do with function code, but because you are using a template node and you left the default Format as Mustache template, it triggers replacements of special mustache braces ! so this means if your own subflow using template nodes and have those braces, the node Paste JSON In Here would attempt to substitute variables which of course won't be found, and will result on empty values in resulting output !! will then mean your node will behave very strange until you exhaust every path to debug, then think hmmm where is that issue coming from until you realise the template nodes in the subflow behaving strange compared to using it as just simply a subflow within a flow, and then voilĂ  ! of course simply changing the Format of Paste JSON In Here template to Plain Text would resolve this ! I know it's long story but hey it drove me nuts to find cause it forced me to re-test every part of my subflow !! so gotta say it surely did fix me up baby! :grin:

1 Like

I think you definitely deserve the 'Debugger of the Month` award for finding that. I can imagine it was a nightmare to track down.

2 Likes

Nice Spot @nileio :man_bowing:

@Colin, can you edit with the below? - I dont have the rights being it's been too long.

updates:

  • Set to Plain Text
  • Output as JSON
[{"id":"b7329b63e35ef370","type":"tab","label":"Subflow To Module Helper","disabled":false,"info":"","env":[]},{"id":"5ad4c1667cdee07f","type":"inject","z":"b7329b63e35ef370","name":"Generate","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":200,"y":145,"wires":[["8289fb654090dedd"]]},{"id":"0c8644b1b01426f4","type":"function","z":"b7329b63e35ef370","name":"Fix me up baby!","func":"let parsedObject = msg.payload\n\nparsedObject = parsedObject.filter((n) => !n.type.startsWith(\"subflow:\"))\n\nconst nodes = parsedObject.filter((n) => n.type !== 'subflow')\nconst subflow = parsedObject.filter((n) => n.type === 'subflow')[0]\n\nmsg.payload  = {\n    ...subflow,\n    flow:[...nodes]\n}\n\nreturn msg","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":215,"y":275,"wires":[["469ac5aae85ef83f"]]},{"id":"8289fb654090dedd","type":"template","z":"b7329b63e35ef370","name":"Paste JSON In Here","field":"payload","fieldType":"msg","format":"json","syntax":"plain","template":"","output":"json","x":225,"y":210,"wires":[["0c8644b1b01426f4"]]},{"id":"469ac5aae85ef83f","type":"debug","z":"b7329b63e35ef370","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":445,"y":275,"wires":[]}]

Flow updated

1 Like

Oh yeah sure did!! was a thorough mind training !! :smile: