# BestPractice to reuse Subflow and set paramters for specific instance?

**URL:** <https://discourse.nodered.org/t/bestpractice-to-reuse-subflow-and-set-paramters-for-specific-instance/84247>\
**Category:** General\
**Tags:** function-node, uibuilder\
**Created:** [3 January 2024 10:11 UTC](https://discourse.nodered.org/t/bestpractice-to-reuse-subflow-and-set-paramters-for-specific-instance/84247 "2024-01-03T10:11:40Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![daspixel](https://avatars.discourse-cdn.com/v4/letter/d/db5fbb/32.png) [@daspixel](https://discourse.nodered.org/u/daspixel)\
**Post date:** [3 January 2024 10:11 UTC](https://discourse.nodered.org/t/bestpractice-to-reuse-subflow-and-set-paramters-for-specific-instance/84247/1 "2024-01-03T10:11:40Z")

</div>

Hi,

I wanted to create a function that gets

- 1 dynamic parameter
- 4 static parameters for each instance.

I found that a multi input function node is NOT wanted and why  
**I can fully understand and accept this!**  
(I do not want to bring this up again: [Suggestion: A simple way to implement multiple input nodes](https://discourse.nodered.org/t/suggestion-a-simple-way-to-implement-multiple-input-nodes/66630) 😶 )

my subflow looks like this:

```auto
// set some Values in a UIBUILDER driven GUI

// define a basic default set - for the case garbage comes in
// so we can handle or debug better within the GUI
let myMsg = { topic: "Nd", payload: "Nd" }
let myNewPayload = "-";

// here we build the parameters we need in the GUI
// this values would be nice to define outside the subflow 
// so the (sub)flow has not to be copied around and changed
myNewPayload = { 
    "elementtype": "id", // could be id/class/attribute
    "elementselector": "ccc-hatch", // any CSS selector
    "todo": "set", // set/add/remove/toggle
    "targettype": "data-status", // innerHTML, any attribute e.g. data-* (more to come)
    "targetvalue": msg.payload // the value whatever you want to be
};

myMsg.topic = "updateElement: ccc-hatch";
myMsg.payload = myNewPayload;

return myMsg;

```

So what would be the fastest and cleanest way to set / define those 4 parameters for each instance.  
(They never change for one instance - doing that with join and inject seems much to overloading for about 50 or even more instances)

Building my own node for that is on the plan - but not within 2024 🤣 - just want to get it done

best regards  
Antonio B.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [3 January 2024 10:26 UTC](https://discourse.nodered.org/t/bestpractice-to-reuse-subflow-and-set-paramters-for-specific-instance/84247/2 "2024-01-03T10:26:05Z")

</div>

> [@daspixel](#):
>
> my subflow looks like this:

If your subflow is simply a function node, you would greatly benefit from using the `link-call` node and making a simple subroutine.

Each subflow results in multiple nodes being generated every single node inside X the umber of instances. For example: if your subflow has 10 nodes and you have 50 instances, that is 500 nodes.  
A Link-call subroutine equivalent would be 10 + 2

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/a/d/ad5bb5bba09bf6a2fc5c00d93a731039733983cc.png)

```auto
[{"id":"03caf84ad794a574","type":"inject","z":"eaa6d97a6ede80ab","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"seven","payload":"7","payloadType":"num","x":170,"y":2900,"wires":[["158d0f3af2d3e05a"]]},{"id":"529d2fd7dc616683","type":"inject","z":"eaa6d97a6ede80ab","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"nine","payload":"9","payloadType":"num","x":170,"y":2940,"wires":[["158d0f3af2d3e05a"]]},{"id":"158d0f3af2d3e05a","type":"link call","z":"eaa6d97a6ede80ab","name":"","links":["4057e7d7e66892ce"],"linkType":"static","timeout":"30","x":370,"y":2920,"wires":[["c943c9c28b42ec77"]]},{"id":"c943c9c28b42ec77","type":"debug","z":"eaa6d97a6ede80ab","name":"decorated payload","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":620,"y":2920,"wires":[]},{"id":"2e3f6c78987eb8d1","type":"group","z":"eaa6d97a6ede80ab","name":"My subroutine (much lighter than a subflow)","style":{"fill":"#92d04f","fill-opacity":"0.22","label":true},"nodes":["4057e7d7e66892ce","b5344392fd72a5ad","8c0101828c34f512"],"x":124,"y":2999,"w":312,"h":82},{"id":"4057e7d7e66892ce","type":"link in","z":"eaa6d97a6ede80ab","g":"2e3f6c78987eb8d1","name":"decorate-payload","links":[],"x":165,"y":3040,"wires":[["b5344392fd72a5ad"]]},{"id":"b5344392fd72a5ad","type":"function","z":"eaa6d97a6ede80ab","g":"2e3f6c78987eb8d1","name":"decorate","func":"// set some Values in a UIBUILDER driven GUI\n\n// define a basic default set - for the case garbage comes in\n// so we can handle or debug better within the GUI\n\nconst myMsg = RED.util.cloneMessage(msg);\n\n// here we build the parameters we need in the GUI\n// this values would be nice to define outside the subflow \n// so the (sub)flow has not to be copied around and changed\nconst myNewPayload = { \n \"elementtype\": \"id\", // could be id/class/attribute\n \"elementselector\": \"ccc-hatch\", // any CSS selector\n \"todo\": \"set\", // set/add/remove/toggle\n \"targettype\": \"data-status\", // innerHTML, any attribute e.g. data-* (more to come)\n \"targetvalue\": msg.payload, // the value whatever you want to be\n originalTopic: msg.topic\n};\n\nmyMsg.topic = \"updateElement: ccc-hatch\";\nmyMsg.payload = myNewPayload;\n\nreturn myMsg;","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[],"x":280,"y":3040,"wires":[["8c0101828c34f512"]]},{"id":"8c0101828c34f512","type":"link out","z":"eaa6d97a6ede80ab","g":"2e3f6c78987eb8d1","name":"link out 1","mode":"return","links":[],"x":395,"y":3040,"wires":[]}]

```

* * *

some additional notes:

1. your function disregards the original `msg`. This is not advised. One day, you will encounter an issue where the original `msg` has a property that is required downstream in the flow.
2. you `let` create `myNewPayload` as a string then change it to an object. Better to simply `const` create the object `const myNewPayload = { ... }`
3. you `let` create `myMsg` with a topic and payload, then overwrite them below. Better to `const` create the `myMsg` object e.g. `const myMsg = {}` then simply append final values `

Here is how I restructured your function

```auto

const myMsg = RED.util.cloneMessage(msg);

const myNewPayload = { 
    "elementtype": "id", // could be id/class/attribute
    "elementselector": "ccc-hatch", // any CSS selector
    "todo": "set", // set/add/remove/toggle
    "targettype": "data-status", // innerHTML, any attribute e.g. data-* (more to come)
    "targetvalue": msg.payload, // the value whatever you want to be
    originalTopic: msg.topic
};

myMsg.topic = "updateElement: ccc-hatch";
myMsg.payload = myNewPayload;

return myMsg;

```

---

<div class="post-metadata">

**Author:** ![daspixel](https://avatars.discourse-cdn.com/v4/letter/d/db5fbb/32.png) [@daspixel](https://discourse.nodered.org/u/daspixel)\
**Post date:** [3 January 2024 11:33 UTC](https://discourse.nodered.org/t/bestpractice-to-reuse-subflow-and-set-paramters-for-specific-instance/84247/3 "2024-01-03T11:33:29Z")

</div>

Wow 🫠

Yes 🫢 all my subflows are small functions like this.  
Ups ... so all my small subflows should be changed ...

I will try to update and change those things as soon as possible to prevent using wrong habbits 🙀.  
I guess I will need some time to fully understand and get used to the correct usage.

1. noticed \*
2. & 3. thought a const can not be changed any more \*

\* I will try to improve, remind myself and thank you very much for explaining all the stuff!

I will have to make a snapshot tonight 😆 before touching this

best regards  
Antonio B.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [3 January 2024 11:37 UTC](https://discourse.nodered.org/t/bestpractice-to-reuse-subflow-and-set-paramters-for-specific-instance/84247/4 "2024-01-03T11:37:43Z")

</div>

> [@daspixel](#):
>
> & 3. thought a const can not be changed any more \*

`const` means you cannot change the "thing" - i.e. a `const obj = {}` will always be an `object`, but you _can_ change its properties.

Final note:

The `function` node is rather _heavy_ for simple payload manipulation. when you ditch the subflows, try to change some of the smaller ones to `change` nodes.

also, it is important to give your `link-in` nodes good (and unique) names to make the best of _subroutines_ (the link-in name appears in the `link-call` node)

---

<div class="post-metadata">

**Author:** ![fmarzocca](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/fmarzocca/32/35901_2.png) [@fmarzocca](https://discourse.nodered.org/u/fmarzocca)\
**Post date:** [3 January 2024 12:44 UTC](https://discourse.nodered.org/t/bestpractice-to-reuse-subflow-and-set-paramters-for-specific-instance/84247/5 "2024-01-03T12:44:17Z")

</div>

> [@Steve-Mcl](#):
>
> Each subflow results in multiple nodes being generated every single node inside X the umber of instances. For example: if your subflow has 10 nodes and you have 50 instances, that is 500 nodes.  
> A Link-call subroutine equivalent would be 10 + 2

OT: @Steve-Mcl, this is very interesting. So, in which case you are compelled to use Subflows?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [3 January 2024 12:50 UTC](https://discourse.nodered.org/t/bestpractice-to-reuse-subflow-and-set-paramters-for-specific-instance/84247/6 "2024-01-03T12:50:03Z")

</div>

> [@fmarzocca](#):
>
> So, in which case you are compelled to use Subflows?

no, the opposite.

Link-call is very good for PURE \*1 (and stateless \*2 ) functions & I recommend this style of programming first and foremost.

the issue I attempted to spell out is:

### scenario (subflow):

- subflow1 has 10 nodes
- flows use 50 subflow instances
- therefore, 500 nodes are programmatically instantiated in the core. Some of these may have init and teardown code - that is a lot of work.

### scenario (subroutine):

- subroutine has 10 nodes (plus the link-in + link-out (12 in total)
- flows use 50 link-calls
- therefore, only 12 nodes are programmatically instantiated in the core.

  
  

\*1 A **pure function** is a function which: (a) Given the same input, will always return the same output and (b) Produces no side effects.

\*2 stateful flows can be achieved with link-call by using named context for storage & retrieval, but subflows hide this complexity.

---

<div class="post-metadata">

**Author:** ![fmarzocca](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/fmarzocca/32/35901_2.png) [@fmarzocca](https://discourse.nodered.org/u/fmarzocca)\
**Post date:** [3 January 2024 12:58 UTC](https://discourse.nodered.org/t/bestpractice-to-reuse-subflow-and-set-paramters-for-specific-instance/84247/7 "2024-01-03T12:58:02Z")

</div>

Yes, I got this and maybe I misspelt my question.

Given the consolidated advice to use subroutines whenever possible, when you cannot avoid the use of subflows?

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [3 January 2024 13:04 UTC](https://discourse.nodered.org/t/bestpractice-to-reuse-subflow-and-set-paramters-for-specific-instance/84247/8 "2024-01-03T13:04:15Z")

</div>

Not sure if there is really a question there, but to round it off, my personal recomendation is:

- try to program without side-effects use link-call first.
- if you need state (i.e. something is updated/remembered and that value can affect the next message or the flow output) then use regular flows UNLESS you need it more than once, then package it up into a subflow.

---

<div class="post-metadata">

**Author:** ![fmarzocca](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/fmarzocca/32/35901_2.png) [@fmarzocca](https://discourse.nodered.org/u/fmarzocca)\
**Post date:** [3 January 2024 13:26 UTC](https://discourse.nodered.org/t/bestpractice-to-reuse-subflow-and-set-paramters-for-specific-instance/84247/9 "2024-01-03T13:26:24Z")

</div>

Yes.  
I have another question on subroutines, but I'll open a new thread, not to clutter this one.  
Thanks

---

<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:** [3 March 2024 13:26 UTC](https://discourse.nodered.org/t/bestpractice-to-reuse-subflow-and-set-paramters-for-specific-instance/84247/10 "2024-03-03T13:26:48Z")

</div>

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