# Singleton Node concept

**URL:** <https://discourse.nodered.org/t/singleton-node-concept/79270>\
**Category:** General\
**Created:** [17 June 2023 10:07 UTC](https://discourse.nodered.org/t/singleton-node-concept/79270 "2023-06-17T10:07:33Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [17 June 2023 10:07 UTC](https://discourse.nodered.org/t/singleton-node-concept/79270/1 "2023-06-17T10:07:33Z")

</div>

Hi There!

Quick question concerning the [singleton pattern](https://en.wikipedia.org/wiki/Singleton_pattern) - is there a best-practice for having singleton nodes? I.e. nodes that can only be included once in a project and/or flow?

I have no specific use-case, just a thought experiment.

But on that note, has anyone considered implementing the [design patterns](https://en.wikipedia.org/wiki/Software_design_pattern) in Node-RED? Is that a thing? Obviously not all would be applicable to Node-RED but Node-RED could be a good way to visually teach people about those concepts...

Cheers!

---

<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:** [17 June 2023 11:19 UTC](https://discourse.nodered.org/t/singleton-node-concept/79270/2 "2023-06-17T11:19:41Z")

</div>

> [@gregorius](#):
>
> Quick question concerning the [singleton pattern](https://en.wikipedia.org/wiki/Singleton_pattern) - is there a best-practice for having singleton nodes? I.e. nodes that can only be included once in a project and/or flow?

A config node (like the MQTT config or the serial config) are in essence singleton nodes.

Additionally, it is trivial to design a flow that makes any node singleton. Here is an example using link-call:

![chrome_oj4bWiaNHJ](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/e/bef968417211d92d9b0d5ed00d4638f551645cd8.gif)

> [@gregorius](#):
>
> But on that note, has anyone considered implementing the [design patterns](https://en.wikipedia.org/wiki/Software_design_pattern) in Node-RED? Is that a thing? Obviously not all would be applicable to Node-RED but Node-RED could be a good way to visually teach people about those concepts

I dont know of such a resource for Node-RED and while it would be not everyones flavour, it may prove useful for folk.

Here are a few good (IMHO) practices that I use and impart when asked (based on many years of programming in many different languages and applications):

- Stay as [PURE](https://dmitripavlutin.com/javascript-pure-function/) as possible (i.e. avoid context, pass data in via the msg, get the result from the msg)
- Learn and understand the JOIN node as early as possible into your Node-RED adventure. It will help you understand one of the most fundamental parts of node-red (i.e. messages NEVER arrive from different wires at the same time)
- Dont shoot the messenger - i.e. try to ALWAYS return the original `msg` object - it may have extra things in that are needed downstream (like dashboard, Link-Call, TCP and HTTP nodes all need the original `msg` since it contains important routing info)
- When to and when not to use a subflow
- Dont loop - use the split and join nodes
- Use the `copy path` button on the debug to avoid typos
- Learn the shortcuts to save time (especially `ctrl+shift+p` then start typing)
- Use the correct mode when deploying
  - many people NEVER change from full deploy to flow or node deploy - and wonder why deploy takes a loooong time and wonder why injects are re-occurring and connections are getting dropped (hint: full deploy completely stops, destroys and re-builds ALL of the flows and nodes node-red server - not just the ones you changed)

- Using `${MY_ENV_VAR}` in the text fields of a node to facilitate common flows that do different things depending on the value set in the computers environment variables ([docs](https://nodered.org/docs/user-guide/environment-variables))
- Best practices in reading/writing to PLCs and industrial controllers (i.e. group multiple reads & writes into single transactions to avoid consistency errors & speeds up comms an order of magnitude)
- Use PARAMETERS for SQL (dont build your own SQL Query as a string - you risk [SQLi](https://portswigger.net/web-security/sql-injection))
- Not programming like its a C++ or an embedded system (i.e. use the event based nature of node/node-red to make things happen, dont poll if avoidable, avoid tight loops (see "Use the split node" above))

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [17 June 2023 13:16 UTC](https://discourse.nodered.org/t/singleton-node-concept/79270/3 "2023-06-17T13:16:35Z")

</div>

> [@Steve-Mcl](#):
>
> Additionally, it is trivial to design a flow that makes any node singleton. Here is an example using link-call:

What I was thinking of was an enforced singleton, i.e. attempting to drag a second instance of a node onto the flow is prevented. So in your case you have several link-call nodes but only one gets called. That is singleton by convention but not enforced. True, what I'm advocating doesn't potentially make sense in Node-RED however knowing this can also be useful.

> [@Steve-Mcl](#):
>
> Here are a few good (IMHO) practices

Thank you for the that list, very interesting - I might well integrate that into an article on Node-RED 🙂 (with reference though!)

> [@Steve-Mcl](#):
>
> Use the `copy path` button on the debug to avoid typos

Hm, didn't see that button on the debug node, I am I missing something?

> [@Steve-Mcl](#):
>
> (i.e. use the event based nature of node/node-red to make things happen, dont poll if avoidable, avoid tight loops

That is so important, remembering that makes life a lot easier and Node-RED faster! It comes down to understanding NodeJS and how everything is basically event-driven.

> [@Steve-Mcl](#):
>
> When to and when not to use a subflow

I would use more subflows if I could integrate them into my node packages, as far as I read, it's either a package with nodes or one with subflows but I can't create a mix of both. Also that I can't add parameters to subflows (at least not in the editor) is a drawback for me.

Being honest, I end up doing a lot of copy and paste instead of creating subflows - not the best solution.

---

<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:** [17 June 2023 14:09 UTC](https://discourse.nodered.org/t/singleton-node-concept/79270/4 "2023-06-17T14:09:29Z")

</div>

> [@gregorius](#):
>
> Being honest, I end up doing a lot of copy and paste instead of creating subflows - not the best solution.

That is where link-call shines. It kinda promotes PURE functions (by virtue you have to pass in all the stuff via msg and get the answer back from the msg)

> [@gregorius](#):
>
> > [@Steve-Mcl](#):
> >
> > Use the `copy path` button on the debug to avoid typos
> 
> Hm, didn't see that button on the debug node, I am I missing something?

There’s a great page in the docs ([Working with messages : Node-RED](https://nodered.org/docs/user-guide/messages)) that will explain how to use the debug panel to find the right path to any data item.

Pay particular attention to the part about the buttons that appear under your mouse pointer when you over hover a debug message property in the sidebar.

![BX00Cy7yHi](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/d/bd1f333a9e043b061b39917c328b0094d3e52d30.gif)

---

<div class="post-metadata">

**Author:** ![gregorius](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/gregorius/32/73816_2.png) [@gregorius](https://discourse.nodered.org/u/gregorius)\
**Post date:** [17 June 2023 14:22 UTC](https://discourse.nodered.org/t/singleton-node-concept/79270/5 "2023-06-17T14:22:12Z")

</div>

> [@Steve-Mcl](#):
>
> Pay particular attention to the part about the buttons that appear under your mouse pointer when you over hover a debug message property in the sidebar.

Ok, sorry I assumed that it was something directly on the debug node. I mostly use tab-completion in the editor if I write out paths. I try to avoid using the mouse when coding, so I don't like the _scroll, click, uncollapse hierarchy, click, copy path, click/cmd-c, paste_ routine 🙂

btw I hope you're not trying to say something with `payload: "birth"` - if so, then congrats! 😉

---

<div class="post-metadata">

**Author:** ![drmibell](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/drmibell/32/8424_2.png) [@drmibell](https://discourse.nodered.org/u/drmibell)\
**Post date:** [18 June 2023 02:14 UTC](https://discourse.nodered.org/t/singleton-node-concept/79270/6 "2023-06-18T02:14:28Z")

</div>

> [@gregorius](#):
>
> What I was thinking of was an enforced singleton, i.e. attempting to drag a second instance of a node onto the flow is prevented.

It might be possible to use the `nrlint` tool to do this (untested). You could define a new node category "singleton", similar to "common" or "function". Then write an `nrlint` rule so that for any node type in the singleton category, creating a new instance when one already exists will generate an error. This should be easy to check for anyone (not me) who knows how to write `nrlint` rules, since it could be tested against an existing node category, without having to write a new custom node.

---

<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:** [17 August 2023 02:15 UTC](https://discourse.nodered.org/t/singleton-node-concept/79270/7 "2023-08-17T02:15:23Z")

</div>

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