Global Function for multiple Function Nodes

Is there a way to have a set of functions loaded into a global or flow space that i can use in multiple function nodes?

I use function nodes alot to do formatting and other such things and depending on the flow I will have a single function in each of these nodes written out 5 - 10+ times. Is there a smarter way to call functions rather than repeating the code in each function node?

You can add an utility object full of functions to global context*. Or you can add them in settings.js.

*Is your global context memory or file backed?


other options...

Update
Node-red now has the built in link call node that provides subroutine capability.

This is what I use a lot: Importing function from another node - #6 by kuema

Nice, I think I missed that one, thanks. :nerd_face:

2 Likes

I found the solution around the time you guys were posting. I put a function node in at the start of my flow with the following text in it and it works perfectly.

To call the functions I need the following in every node I want to use my fuctions in.

var Func = flow.get('Func');

To call the functions I now need to use the Func. prefix so GrantAccess becomes Func.GrantAccess

Func = {
    GrantAccess : function (haystack, arr) {
                return arr.some(function (v) {
                return haystack.indexOf(v) >= 0;
                })},
            pad : function (num, size) {
                var s = num+"";
                while (s.length < size) s = "0" + s;
                return s;
                },
    DaysBetween : function (date1, date2) {
                var one_day=1000*60*60*24;
                var date1_ms = date1.getTime();
                var date2_ms = date2.getTime();
                var difference_ms = date2_ms - date1_ms;
                difference_ms = Math.round(difference_ms/1000,3);
                var mseconds = difference_ms % 1000;
                var seconds = Math.floor(difference_ms % 60);
                difference_ms = difference_ms/60; 
                var minutes = Math.floor(difference_ms % 60);
                difference_ms = difference_ms/60; 
                var hours = Math.floor(difference_ms % 24);  
                var days = Math.floor(difference_ms/24);
                return Func.pad(minutes,2) + ':' + Func.pad(seconds,2) + '.' + Func.pad(mseconds,3);
                },
    GetPriority : function (priority) {
                var PriorityTable = { 64:"Low", 
                16384:"Below Normal", 
                32:"Normal", 
                32768:"Above Normal", 
                128:"High",
                256:"Realtime"
    			};
                return (PriorityTable[priority])
                }
    }

flow.set('Func', Func);
node.status({fill:"green",shape:"dot",text:"Functions Loaded"});
2 Likes

Just note that this method only works with the default in-memory context store, if you ever change default stores, it will fail. There is also no guarantee that even the in-memory store will work this way in the future. The reason is that you cannot easily serialise a JavaScript function. The in-memory store currently doesn't need to serialise but all other stores do.

The only place you can totally rely on this working is by putting the function into settings.js either directly or by requiring it as a module from an external file.

What is the default in memory context store and why would I need to change it?

The reason im reluctant to change the settings.js file is because I am building these flows for in some cases non technical people to install and operate. The easier it is for them to get it working the better.

The default is the standard store used by Node-RED if you don't change any settings. Node-RED also has a file-based store that persists your context variables to file so that restarting Node-RED doesn't lose everything. You can make any available store the default. People may well develop other stores in the future, I think there is a REDIS based one somewhere.

The point is that, while what you have done may work now, there is no guarantee that it will continue to work in the future or for someone else.

So that really depends on how you are deploying your node-red environment for them. Assuming that you at least have to distribute a template userDir folder - that contains the flow and other key files, it is no harder to also distribute a settings.js file. In fact, it isn't that hard to have an installation script that will do everything including installing Node-RED, any required nodes and other modules and provides pre-configuration and flows.

It really depends on what is important to you and to your users.

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