I guess this may be one for @knolleary when he is back from his hols but ...
When you do RED.nodes.createNode(this, config) for you node instance, why doesn't createNode apply config to this for you?
It seems a long-winded step to have to go and individually apply the config properties to this yourself.
I am looking at the best ways to decompose the node runtime definiton and I think I've come a long way now. With some simple tricks it is possible to get a much clearer and more robust structure. I will post my progress to another thread shortly though some of the thinking is here:
Because it didn't occur to us (me) to do something like that until it was too late to consider without potentially breaking nodes that didn't expect that behaviour.
OK, thanks for that. It isn't a big deal - however, maybe something that could be improved (in a backwards compatible way of course) in a future release?
I'm also finding it facinating how that function treats this in a way that hadn't occured to me could happen.
Basically, when using a function outside of the export. If you try to access this before the call to createNode, you can not. But if you try afterwards, you can! Very strange - though I'm sure there will be an answer I'm too thick to have comprehended
Just writing up a minimal example node definition using what I've discovered so far about destructuring the code.
But you cannot guarantee it. A node may have some logic around setting this.foo based on the value of config.foo and other properties. If we unilaterally set it, it would break. I remember finding a concrete examples of this when I looked at it a few years ago.
The node object, with all of its internal workings, hasn't been created until you call createNode. That is why it's the first thing the node constructor function needs to do.
Thanks for the explanation Nick, that makes sense.
It is just weird that you HAVE to pass this (I tried it with something else ) even though you cannot actually reference this in your code until after the call.
I'm sure there is a logical reason for it, it just doesn't look logical. However, it works and I'm using it. So not worth disturbing anyone about.
Forcing me to learn more about the inner workings of Node-RED!
class MyCustomNode {
constructor(config) {
createNode(this, config);
}
}
It would be awesome if it could be:
class MyCustomNode extends CreateNode {
constructor(config) {
super(config);
}
}
EDIT: I just ran a quick and dirty test to see what createNode does. It seems that the main thing it does is to attach any credentials to the Node object.
I was able to extend the Node class to create a functional node-red node without the need to call createNode like this:
It simply worked (probably because my node does not use credentials). If the credential grabbing logic was moved from createNode to the Node class constructor, then createNode seems like it could remain backwards compatible, while also allowing the Node class to be exportable to be used as shown above with the extends class syntax.
There have been some nodes implemented using 'true' JavaScript classes.
You're right they are largely compatible and possibly a clearer way to structure things. If we were to change our recommended approach, I suspect this would be more akin to what we'd do.