Isomorphic functions (same in both .html and .js)

Hi community,

I'd be so grateful for a pointer or two as I spent the better part of the day trying to solve this:

I need to execute an isomorphic function, i.e. both on the server (myNode.js) and the client (myNode.html).

I've tried defining the function inside the .html's defaults section, and then going this.fn = config.fn in the .jsfile. No luck there...

Grateful for any help – and keep up this awesome community :>

I think it might help if you give some more details of what you are trying to achieve, and why.

Hi Christian,
I have always assumed that this is not possible, but perhaps I'm totally wrong.
Thought the only way this is possible, is to "workaround" it like this:

  • Create a mylibrary.js file with your shared functions
    exports.myfunction = function(aparameter) {
          ...
    }
    
  • Use that js file in your backend js file:
    module.exports = function(RED) {
       // For example when the library file is in the same folder as the backend js file
       const utils = require('./mylibrary');
     
       function MyCustomNode(config) {
          RED.nodes.createNode(this, config);
          ...
          mylibrary.myfunction(someArgument);
       }
    }
    
  • And if you want to have the same function on the client, you need to add a script tag in your html file (to download it from your Node-RED server):
    <script src="my_custom_node/anOptionalDirectoryName/aFileName.js"></script>
    
    But this means your backend code should provide that file to your client:
    RED.httpAdmin.get('/my_custom_node/*', function(req, res){ 
         if (req.params[0].startsWith("anOptionalDirectoryName/")) { 
             var options = {
                 root: __dirname,
                 dotfiles: 'deny'
             };
         
             // Send the requested js library file to the client
             res.sendFile(req.params[0], options);
         }
    }
    

So not perhaps an correct answer to your question. Because this way you not simply include the library in both client and server files. Instead the server makes the library file available to the client, so at least it allows you to reuse the same library functions both on client and server.

Good luck with it,
Bart

1 Like

Nothing fancy really – it's a currency formatting function, and I want to make dead sure that currencies are formatted the same way on the server as in the client's status field.

Thanks Bart for the suggestion and taking your time. Your solution introduces an amount of boilerplate for a simple one-line function, but makes a lot of sense in the case of sharing libraries.

Nevertheless you made me realise I can call the formatting function on the server side and do a:

RED.comms.publish("myUpdate",node.formattedValue);

...and pick it up the formatted value on the client side with a:

RED.comms.subscribe("myUpdate", ... );

1 Like

The comma interface is not a documented API and subject to possible change. For a one line function cut and paste is much more sensible.

2 Likes

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.