Share functionality between nodes

I have now extracted the core functionality from the node-red-contrib-msg-speed, and moved it to a new nr-msg-statistics package.

For anybody who needs to do something similar in the future, below you can find how I did it. Although there might be many ways to get to Rome ... But since I have a background as object oriented developer, I really wanted to use ES6 classes to accomplish this. So no callback functions for me this time :roll_eyes:

  1. In the new Github repository, I encapsulated all the shared functionality into a class (which will be exported):

    module.exports = class MessageAnalyzer {
       constructor (config) {
         // Do some initialization, and store the Node-RED node config into this instance
         this.someProperty = config.someProperty;
         ...
       }
     
       someMethod(someParameter) {
          ...
          this.doSomething();
          ...
          this.doSomethingElse();
          ...
       };
    
       doSomething() {
       }
    
       doSomethingElse() {
       }
    }
    
  2. The someMethod contains my old logic (of the speed node), which I want to reuse in other nodes.
    But at some points in the code I call the (e.g. empty) methods doSomething and doSomethingElse.

  3. I added the new npm package as a dependency in the package.json file of my speed node:

     "dependencies": {
         "nr-msg-statistics": "^1.0.0"
     },
    
  4. The speed node now imports this class, and creates a subclass of it. That subclass will override the methods doSomething and doSomethingElse to do stuff that is specific to this speed node:

    module.exports = function(RED) {
       function speedNode(config) {
          RED.nodes.createNode(this, config);
         
          var node = this;
         
          const MessageAnalyzer = require('nr-msg-statistics');
         
          class MessageSpeedAnalyzer extends MessageAnalyzer {
             doSomething() {
                 // Do some speed related stuff
             }
     
             doSomethingElse() {
                 // Do some other speed related stuff
             }
         }
         
         // Create an intance of the subclass
         var messageSpeedAnalyzer = new MessageSpeedAnalyzer(config);
    
         // By calling this method, underneath the doSomething and doSomethingElse will be called.
         messageSpeedAnalyzer.someMethod(...);
       }
    }
    

So I can reuse the code (in the MessageAnalyzer class) to share it between multiple Node-RED nodes, and each node can overwrite the methods to do stuff that is specific to that node ...

Damn it was fun working with classes after a long time :clinking_glasses:

2 Likes