0

I'm learning how to create my own node-red node by following the tutorial Creating your first node. If you take a look below, you can see that this is saved in the variable node so that you can send a message when an 'input' event is received. That's fine, but why continue using this to register the 'input' event?

module.exports = function(RED) {
    function LowerCaseNode(config) {
        RED.nodes.createNode(this,config);
        var node = this;
        this.on('input', function(msg) {
            msg.payload = msg.payload.toLowerCase();
            node.send(msg);
        });
    }
    RED.nodes.registerType("lower-case",LowerCaseNode);
}

Couldn't we replace this.on('input', function(msg) with node.on('input', function(msg)?

tchau.dev
  • 903
  • 1
  • 11
  • 30
  • Couldn't we also replace `RED.nodes.createNode(this,config);` with `RED.nodes.createNode(node, config);`? – Bergi Mar 01 '17 at 23:02

2 Answers2

2

Of course we could, but why would we? The only reason to store node is so that we can use it in the closure, and that is where we'll use it - and only there. Notice that there are also many solutions to this problem that don't need an extra variable at all. In modern code (ES6), they are actually preferable.

Community
  • 1
  • 1
Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • 1
    For completeness, until the most recent release, Node-RED still supported node 0.10, so ES6 features were not available. Hence why this particular pattern is so widely evident. – knolleary Mar 01 '17 at 23:10
  • The reason why I ask this question is because I've seen code base where `node` is use outside of the closure (where `this` could be use). – tchau.dev Mar 01 '17 at 23:45
  • @tchau.dev Given that it makes absolutely no difference in execution, it comes down to personal preference. In the case of `node` its even the same number of letters to type. I would however argue that `this` stands out as an identifier, and it's clear (by convention) that it refers to the instance, so it makes for more readable and consistent code that doesn't use different identifiers in every class. See also jfriends excellent (agreeing with me :P) answer. – Bergi Mar 02 '17 at 00:32
  • That's good to know. The last thing I want to hear is something node-red specific. Thanks. – tchau.dev Mar 02 '17 at 00:33
2

Couldn't we replace this.on('input', function(msg) with node.on('input', function(msg)?

Yes, you could.

That's fine, but why continue using this to register the 'input' event?

There are generally two styles of coding when you choose to assign this to another variable so it can be used in a closure.

Style #1 - Assign the new variable at the top of the function and then use it everywhere in the function.

Style #2 - Use the new variable only in the closure where this is not the desired value.

I've seen both in practice so it is really just a matter of personal style which you prefer. For example, here's a question about methods that start with var me = this; and then use me everywhere in the function.

Personally, I prefer style #2 because I think code is more self explanatory when you use this everywhere you can.

And, of course in an ES6 environment or when transpiling from ES6, you can use an arrow function to preserve the lexical value of this for use in the closure:

module.exports = function(RED) {
    function LowerCaseNode(config) {
        RED.nodes.createNode(this,config);
        this.on('input', msg => {
            msg.payload = msg.payload.toLowerCase();
            this.send(msg);
        });
    }
    RED.nodes.registerType("lower-case",LowerCaseNode);
}

If you call this style #3, this is my new favorite when coding in ES6 is an option and there is no other value of this that you need access to in that function.

FYI, one could also use .bind() on the function to set the value of this too.

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979