Calling an NPM module from a function within a function

I'd be grateful for some help here. I attach two examples of functions, one works, the other doesn't.

I have simplified the problem down to these trivial examples.

I am trying to use external NPM modules from within a function within a function. This used to work in earlier versions of Node Red.

We now have the capability to import the module in the Setup tab of the function, plus the ability to declare the function in the Start up tab. This works fine for code in the main function, but not for sub-functions.

e.g.

function test(bearing1, bearing2){
    var angles = global.get('angles'); 
    angles.SCALE = 360;
    result = angles.shortestDirection(bearing1,bearing2);
    return result;
}
msg.payload = test(10,40);
return msg; 

Fails on the line beginning angles.SCALE with the following error:

TypeError: Cannot set property 'SCALE' of undefined

I'm sure the solution is simple, but I'm not seeing it!
Thanks, Anthony

[{"id":"ebe6ef9a.e68668","type":"function","z":"a71368ab.5a8df8","name":"Test in function","func":"function test(bearing1, bearing2){\n    var angles = global.get('angles'); \n    angles.SCALE = 360;\n    result = angles.shortestDirection(bearing1,bearing2);\n    return result;\n}\nmsg.payload = test(10,40);\nreturn msg; ","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\nvar angles = global.get('angles'); // See https://www.npmjs.com/package/angles\n","finalize":"","libs":[{"var":"angles","module":"angles"}],"x":700,"y":300,"wires":[["c2fbad64.25cb28"]]},{"id":"88135c0.ae96f28","type":"function","z":"a71368ab.5a8df8","name":"Test not in function","func":"angles.SCALE = 360;\nbearing1 = 10;\nbearing2 = 40;\nresult = angles.shortestDirection(bearing1,bearing2); //+1=clockwise, -1==anti-clockwise\nmsg.payload = result;\nreturn msg; ","outputs":1,"noerr":0,"initialize":"// Code added here will be run once\n// whenever the node is started.\nvar angles = global.get('angles'); // See https://www.npmjs.com/package/angles\n","finalize":"","libs":[{"var":"angles","module":"angles"}],"x":710,"y":340,"wires":[["6b052fb3.d27358"]]},{"id":"c77c22d3.308278","type":"inject","z":"a71368ab.5a8df8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":500,"y":300,"wires":[["ebe6ef9a.e68668"]]},{"id":"6a3353be.e45854","type":"inject","z":"a71368ab.5a8df8","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":520,"y":340,"wires":[["88135c0.ae96f28"]]},{"id":"c2fbad64.25cb28","type":"debug","z":"a71368ab.5a8df8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":910,"y":300,"wires":[]},{"id":"6b052fb3.d27358","type":"debug","z":"a71368ab.5a8df8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":910,"y":340,"wires":[]}]
1 Like

Nice, I never took the time to test this functionality. Indeed, I could reproduce the issue you mentioned. A quick fix is to comment the line in the "On message" tab for the function node that is troubled.

function test(bearing1, bearing2){
    //var angles = global.get('angles'); 
    angles.SCALE = 360;
    result = angles.shortestDirection(bearing1,bearing2);
    return result;
}
msg.payload = test(10,40);
return msg; 

At first I found strange (or at least redundant) to get the module twice: in the tab "On start" and then again in the tab "On Message". Anyway this is my first contact with this functionality so I need to read the documentation to fully understand it.

PS: by the way, the NPM module "angles" seems to be very useful. Nice to learn it exists.

Many thanks. Your solution works and is simple.

When you add a module in "Setup", the "Import as" name is made available to the function tabs...

image

... so you dont need to declare it nor do you need to set/get it from context.

1 Like

I see now. So no need to manually install the module, no need to edit settings.js, no need of using "global.get". ...just brilliant.

1 Like

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