# Proper way to define & namespace functions in a node

**URL:** <https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871>\
**Category:** Developing Nodes\
**Created:** [6 December 2019 16:23 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871 "2019-12-06T16:23:47Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![fahrvergnuugen](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/fahrvergnuugen/32/818_2.png) [@fahrvergnuugen](https://discourse.nodered.org/u/fahrvergnuugen)\
**Post date:** [6 December 2019 16:23 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/1 "2019-12-06T16:23:47Z")

</div>

When writing client side static JS functions, what is the proper way to define and then call them so they are specific to the node I am creating?

Are we supposed to declare functions within the registerType call? If so, how do you call the function?

```auto
 RED.nodes.registerType(‘my-custom-node’,{
	oneditprepare: function(){
		console.log("prepare this node");
		renderTable('table-container-id'); // <- where to define and how to call my own function?
	},
	renderTable: function(tableContainerId){
		// render a table
	}
}

```

Further, how would I re-use renderTable in all of my package's nodes?

if I define my function outside the `registerType` call, I end up with a global function which could obviously create a collision.

---

<div class="post-metadata">

**Author:** ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)\
**Post date:** [6 December 2019 16:48 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/2 "2019-12-06T16:48:37Z")

</div>

If all of your nodes are defined in the same file, then you can wrap all of your code in a self-executing function to keep the scope private to the file:

```auto
(function() {

   function renderTable(tableContainerId) { ... }
   
   RED.nodes.registerType("node-one", {....})

   RED.nodes.registerType("node-two", {....})

})();

```

In other words, everything inside that enclosing function can see `renderTable`, but nothing outside of it can.

If you nodes are split across multiple files, it gets a bit more involved.

Previously, we've suggested putting them in your own separate `.js` file and then use a custom admin end point to serve up the file and a `<script>` tag in your node's html to load it in. That has never been an entirely satisfactory answer as it involves too many pieces for what ought to be a relatively straight forward task. Plus it is still loading the code into the global namespace.

Another option that I hadn't considered before is what you propose in your question - essentially adding the function to one of your node's type definitions. You can then access that from anywhere else with:

```auto
RED.nodes.getType("my-custom-node").renderTable("xyz");

```

I can't immediately see why that wouldn't work.

The final option is, as you say, just declare a global function that is visible to everything and pick a name that is unlikely to cause a clash - for example, prefix it with your node-type in some format.

---

<div class="post-metadata">

**Author:** ![kuema](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/kuema/32/6542_2.png) [@kuema](https://discourse.nodered.org/u/kuema)\
**Post date:** [6 December 2019 16:48 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/3 "2019-12-06T16:48:54Z")

</div>

You could use an IFFE and create your own namespace in a function.

`(function () { /* ... */ })();`

EDIT: Okay... what Nick said, he was faster and has a better example. 😁

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [6 December 2019 18:38 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/4 "2019-12-06T18:38:48Z")

</div>

Depending on the need, another possibility would be an API so that the core node definition carries the processing.

* * *

> [@knolleary](#):
>
> I can't immediately see why that wouldn't work.

Would that appear in the pallet?

---

<div class="post-metadata">

**Author:** ![fahrvergnuugen](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/fahrvergnuugen/32/818_2.png) [@fahrvergnuugen](https://discourse.nodered.org/u/fahrvergnuugen)\
**Post date:** [6 December 2019 18:41 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/5 "2019-12-06T18:41:28Z")

</div>

I'm trying the `getType` approach. I'm defining all of my functions under my highest level config node and then setting a reference to it with `getType` anywhere I need to use those functions.

---

<div class="post-metadata">

**Author:** ![fahrvergnuugen](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/fahrvergnuugen/32/818_2.png) [@fahrvergnuugen](https://discourse.nodered.org/u/fahrvergnuugen)\
**Post date:** [6 December 2019 18:41 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/6 "2019-12-06T18:41:56Z")

</div>

Why would the pallet be affected?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [6 December 2019 18:43 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/7 "2019-12-06T18:43:40Z")

</div>

> [@fahrvergnuugen](#):
>
> Why would the pallet be affected

I can't remember what defines an entry in the pallet. Is it the .html file or the .js file or a combination of those and the package.json entry?

---

<div class="post-metadata">

**Author:** ![fahrvergnuugen](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/fahrvergnuugen/32/818_2.png) [@fahrvergnuugen](https://discourse.nodered.org/u/fahrvergnuugen)\
**Post date:** [6 December 2019 18:45 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/8 "2019-12-06T18:45:57Z")

</div>

> I can't remember what defines an entry in the pallet. Is it the .html file or the .js file or a combination of those and the package.json entry?

I'm just adding new properties to the node's registration. Those properties aren't used by NR to render the node, so the pallet shouldn't be affected. But those properties are accessible from any other node's HTML file by using the `getType` method, so it makes for a convenient place to define and namespace all of my functions.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [6 December 2019 18:46 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/9 "2019-12-06T18:46:46Z")

</div>

> [@knolleary](#):
>
> wrap all of your code in a self-executing function to keep the scope private to the file

Drat! There is just too much complexity to track in JavaScript for an amateur programmer!

... hunts for VScode to make sensible changes to uibuilder that he'd never thought about!! ...

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [6 December 2019 18:50 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/10 "2019-12-06T18:50:57Z")

</div>

Some of the options in the `registerType` function impact the pallet - like I said, I can't remember what impact that might have. I assume none since you aren't likely to set them but I don't know for sure which is why I asked Nick.

---

<div class="post-metadata">

**Author:** ![fahrvergnuugen](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/fahrvergnuugen/32/818_2.png) [@fahrvergnuugen](https://discourse.nodered.org/u/fahrvergnuugen)\
**Post date:** [6 December 2019 18:52 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/11 "2019-12-06T18:52:38Z")

</div>

Yeah, there are definitely "reserved" properties... [I think this is the list](https://nodered.org/docs/creating-nodes/node-html)

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [7 December 2019 01:51 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/12 "2019-12-07T01:51:28Z")

</div>

BTW, looks like you just need the `category` entry for your node to turn up in the palette.

---

<div class="post-metadata">

**Author:** ![fahrvergnuugen](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/fahrvergnuugen/32/818_2.png) [@fahrvergnuugen](https://discourse.nodered.org/u/fahrvergnuugen)\
**Post date:** [9 December 2019 15:00 UTC](https://discourse.nodered.org/t/proper-way-to-define-namespace-functions-in-a-node/18871/13 "2019-12-09T15:00:06Z")

</div>

For anyone coming across this who is looking for an example:

[Here I'm adding a method to my node's type definition](https://github.com/PaulWieland/node-red-contrib-insteon/blob/ef6ebcc165257b7be567139b1f030e0c7f54abfe/src/device/insteonDeviceConfig/insteonDeviceConfig.html#L32)

 ![Screen Shot 2019-12-09 at 10.00.49 AM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/f/ff13642c5c4809d20a3cac1c4ee14787fc057f2a.png)

[And then I'm calling it over here.](https://github.com/PaulWieland/node-red-contrib-insteon/blob/ef6ebcc165257b7be567139b1f030e0c7f54abfe/src/device/insteonDeviceConfig/insteonDimmableLightingDeviceConfig/insteonDimmableLightingDeviceConfig.html#L22)

 ![Screen Shot 2019-12-09 at 10.01.04 AM](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/7/71b49e808c6f0b6324e722fdd9003db651d424c1.png)
