Hi experts,
In my custom-developed nodes, I maintain & work with local (per node instance) properties.
What would be the difference (and better way of doing this):
Option 1: as function variables
module.exports = function(RED)
{
function myFunction(config)
{
RED.nodes.createNode(this,config);
const node = this;
var myProperty = 123;
var myProperty2 = "abc";
...
If these are more configuration values (that can change via the HTML file) as opposed to internal states, then you should be using the node properties API
Thanks @marcus-j-davies !
That's my preference as well, enabling me to avoid scope issues and be able to pass less arguments in my inner workings.
My concern is whether by modifying a framework object (node) I will not be stepping on anyone's toes, or that some framework code may impact my properties...
createNode adds the property credentials to your object so maybe don't mess with that or id (or anything beginning with _ )
I and others attach internal state objects all the time, as long as they don't interfere with anything that is added by the runtime - i cant see it being a problem.
The node instance is isolated - there is no overlap elsewhere unless you deliberately target global.
However, as your (if your) code gets larger and more complex, you may wish to refactor it into other modules. At that point, you will be glad you added the variables as properties on the node instance's this object (which most people interpret as node) since you can simple pass this as a reference to your module functions/methods.
You will see that the export is on a separate line so that it gets a named function. Then the exported function calls a setup function and registerType, nothing else. The registerType includes nodeInstance as its callback so that you don't get confused by which bits are part of the overall module and which are specific to the instance. nodeInstance does the usual things except that it does not create the unnessary node variable. However, wherever this is passed to another function/method, the receiving function always calls it node.
The other thing of note is that I create a module-level (think of that as the "local global" ) object to hold data for the module as a whole but that may still need to be passed to other includes. Things like the name of the node for example.
The numbered comments in the code show what order things happen in so there is no confusion.
This approach really helped me get to grips with the order of things and with the isolation/availability of variables.
Well, turns out there is another option - setting custom properties in the node instance, without changing the node object, while avoiding any variable scope issues:
But that isn't the same at all. You are not setting values on the node instance but actually in the Node-RED context store (albeit in the area dedicated to that node). That context store could be set up differently on different Node-RED instances. So it might, for example, be set for persistent storage. While that might be what you want, it may well not be.
So you are not avoiding scope issues, you are merely swapping one set of considerations for another.
Oh, and of course, the context store can be examined by anyone with Editor access. Again that might be helpful or it might not be.