functionGlobalContext on Raspberry PI

Hello everybody,

I have a problem with loading an external function on a Raspberry PI.
To load the module I added it in the "settings.js".

functionGlobalContext: {
		arfunc:require('to-array')
}

In the function-node I include it.

var arFunc = context.global.get('arfunc');

On my Win10 notebook it works fine, but on the rasp i get an error.

21 Oct 21:28:39 - [error] [function:DataToJSON] TypeError: Cannot read property 'toArray' of undefined

I stopped and started node red several times, but it didn't solve it. :laughing:
Any ideas, what I'm doing wrong? :thinking:

Thanks in advance for any answer!

Cheers KeMa

As per documentation:

functionGlobalContext: { osModule:require('os') }

can be accessed in a function node as:

var myos = global.get('osModule');

Wow,

this was a really quick response, thank you bakman2! :+1:

I changed the function node, but unfortunately I get the same error.

@KeMa what versions of Node.js and Node-RED are you running on the Win10 notebook and on the Pi?

On win10 I'm running

20 Oct 14:35:08 - [info] Node-RED version: v0.20.7
20 Oct 14:35:08 - [info] Node.js  version: v10.16.3

on the rasp the latest version

21 Oct 22:33:12 - [info] Node-RED version: v1.0.2
21 Oct 22:33:12 - [info] Node.js  version: v10.16.3

After an update on the win10 to

21 Oct 22:55:39 - [info] Node-RED version: v1.0.2

the flow also runs well.

I made a reinstall on rasp with no effect. Could this problem be related to some rights?

Which directory did you install the module in?

Can you share a bit more of your Function code so we can see how you are trying to use the module?

The location of the folder with the Index.js is

/usr/lib/node_modules/node-red/node_modules/to-array 

I'm using it like that

var datAr = msg.payload;
var arFunc = global.get('arfunc');
var dbg = arFunc.toArray(datAr, 5);

From the docs for the to-array module, the example usage is:

var toArray = require("to-array")
    , elems = document.links
 
var array = toArray(elems)

Note that the toArray function is what the require(...) call returns.

Looking at what you've shared, you are adding the module to global context like this:

arfunc:require('to-array')

This means the arfunc global context value is the toArray function.

Looking at the Function code:

var arFunc = global.get('arfunc');
var dbg = arFunc.toArray(datAr, 5);

You access the global and assign it locally to arFunc. You then try to call .toArray ... but arFunc is already the toArray function you want to use.

This code should be:

var datAr = msg.payload;
var arFunc = global.get('arfunc');
var dbg = arFunc(datAr,5);

Ok, understood!
But now I get the error message

TypeError: arFunc is not a function

I tryed it with the module 'bytes'

functionGlobalContext: {
                arfunc:require('to-array'),
                bfunc:require('bytes')
}

call it

var bytes = global.get('bfunc');
flow.warn(bytes(65535));

and get the error message

TypeError: bytes is not a function

When I send the 'bytes' to a debug-node it is undefined.

I try to understand, how to write and include external functions.

This might suggest the module is not in the correct place.

How did you install these 2 modules?

I don't know your final intended use cases but as a suggestion...

Have you considered using https://flows.nodered.org/node/node-red-contrib-function-npm

This suggests the settings file you are editing is not the settings file Node-RED is using.

Which file are you editing and what settings file does Node-RED log it is using when it starts up?

@knolleary that's it!
I edited the wrong settings file in "/usr/lib/node_modules/node-red" all the time! :man_facepalming:

Thanks a lot to all!:+1:

1 Like