Node-RED 4 function node error

I just installed node-red on a new system using the bash script and ended up with node-red version 4. I imported my flow and it all seemed to work. Then I went into a function node to look at what I'd done years ago. When I closed the function node it has a red triangle on it and says there is a javascript error.

How did this work initially and then decide there was an error after I opened and closed it?

I cut and pasted the javascript code in the node from another instance on different system (that is working) and it still gives the error after I hit "Done".

What has changed to cause this? Here is the code:

 Install point-in-polygon with:
    cd ~/.node-red
    npm install point-in-polygon
 var inside = require('point-in-polygon'); // doesn't work in node-red.
 So must edit .node-red/settings.js and add:
      functionGlobalContext: {
          insidePolygon:require('point-in-polygon')
      }
 Requires a node-red restart when finished.
*/

var inside = global.get('insidePolygon');
msg.InAlertRegion=true;   // default is to accept detection anywhere in image


// screen for LR box point in reagion
var poly=[[]];

// polygon points picked from image using GIMP
if(msg.filename.includes("DriveWay"))
    poly=[ [500,1600], [1550,1200], [2200,700], [3841,500], [3841,1500], [2200, 2161], [1400,2161] ];
else if(msg.filename.includes("CliffwoodNorth"))
    poly=[ [-1,1980], [3500,400], [3840,380], [3840, 2160],[-1,2160] ];
else if(msg.filename.includes("CliffwoodSouth"))
    poly=[ [50,250], [250,750], [3840,1900], [50,1900] ];
//else if(msg.filename.includes("Intersection"))
//    poly=[ [-1,1000], [900,1100], [3841,1500], [3841,2161], [-1,2161] ];
else if(msg.filename.includes("HummingbirdRight"))
    poly=[ [-1,1100], [2400,900], [3841,1650], [3841,2161], [-1, 2161] ];
else if(msg.filename.includes("FrontDoor"))
    poly=[[-1,900], [600,1100], [600,900], [3841,1100], [3841,2161], [-1,2161], ];
else if(msg.filename.includes("HummingbirdLeft"))
    poly=[[1200,850], [500,1600], [-1,2161], [3841,2161], [3841,1000], [3000,1000]];
   
if(poly.length > 2)
    msg.InAlertRegion = inside([msg.endX, msg.endY], poly); // returns false if point not inside polygon
if(msg.InAlertRegion === false)
    return msg; // no need to test for bogus object if out of the alert region.



// filter for box points matching bogus detection of static object
// var bogus=[[ ULx.ULy, LRx,LRy, tol ]];
//
// UL,LR of reject object obtained from bogus AI detection image overlay text
// CamBogus = [ [ startX,startY, endX,endY, tolerence] ]; // multiple bogus detections can be in a frame, so 2D array, N by 5.
var bogus= [ [] ];  // empty 2D array is 1 by 0

/*  Idea is that -y8v option makes these no longer necessary
if(msg.filename.includes("PoolEquipment")){
    bogus=[ [1300,670, 1420,790, 0.8],      // plumbing pipes/valves
            [636,621, 1091,1078, 0.3],      // pool filter tank
            [806,535, 1260,1083, 0.3],      // pool filter tank
            [441,198, 908,810, 0.3] ];      // pool chemical storage cans
}else if(msg.filename.includes("KitchenDoor"))
    bogus=[ [870,255, 1490,650, 0.2] ];    // table on patio
else if(msg.filename.includes("HummingbirdLeft"))
    bogus=[ [2918,235, 3343,916, 0.3] ];    // tree trunk, so far only see these with CPU or NCS AI
else if(msg.filename.includes("MailBox"))
    bogus=[ [883,117, 1606,122, 0.2] ];    // morning shadows on mailbox
else if(msg.filename.includes("SideYard"))
    bogus=[ [864,136, 864,674, 0.2] ];    // afternoon shadows on tarp, so far only see these with CPU or NCS AI
*/    
if(bogus[0].length == 5){
    for (var i=0; i<bogus.length; i++){
        xtol=(bogus[i][2]-bogus[i][0])*bogus[i][4];
        if(Math.abs(msg.startX-bogus[i][0])>xtol){continue}
        if(Math.abs(msg.endX-bogus[i][2])>xtol){continue}
        ytol=(bogus[i][3]-bogus[i][1])*bogus[i][4];
        if(Math.abs(msg.startY-bogus[i][1])>ytol){continue}
        if(Math.abs(msg.endY-bogus[i][3])>ytol){continue}
        msg.InAlertRegion=false;
    }
}

// screen cameras I don't want alerts from for now.
if( msg.filename.includes("Inter")|| msg.filename.includes("Plate") || msg.filename.includes("Reo") ){
    msg.InAlertRegion=false;
}



if(msg.InAlertRegion === true)
    msg.filename=msg.filename.replace("AI", "AI.alert"); // for QA/QC want to know what would trigger alerts.
return msg;

No clue as to what it doesn't like about my javascript code.

You can't use require() in the function code.

The function node config dialog has a Setup tab where you can import external modules. Not sure if this will work for your 'point-in-polygon'

See https://nodered.org/docs/user-guide/writing-functions#using-the-functionexternalmodules-option

Not it. The requires is inside a comment, the delimiters seemed to have disappeared when pasted into the markdown.

Seems local variables now need to be "declared" before using them.

seems that adding:
var xtol, ytol;

in front of the if() where they are used is now required.

if(bogus[0].length == 5){
for (var i=0; i<bogus.length; i++){
xtol=(bogus[i][2]-bogus[i][0])*bogus[i][4];

Who thinks this is progress? Now everytime I open one of my function nodes I'm gonna have to fix this even if I don't do anything else :frowning:

Javascript always required you to declare variable.
It just the new Monaco editor has better error reporting than the old ace, your code should still have ran with the error flags though, if you don't mind the red triangle warnings.

Here is how to use functionexternalmodules, which is an easier way to load modules, check the function node setup tab.

[{"id":"a97a81377c49830f","type":"inject","z":"d1395164b4eec73e","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"75","payloadType":"num","x":150,"y":140,"wires":[["fe4ea62db9ebcbf1"]]},{"id":"fe4ea62db9ebcbf1","type":"function","z":"d1395164b4eec73e","name":"function 157","func":"let  poly=[[1200,850], [500,1600], [-1,2161], [3841,2161], [3841,1000], [3000,1000]];\nmsg.payload = insidePolygon([1500, 1500], poly);\nreturn msg; \n","outputs":1,"timeout":0,"noerr":0,"initialize":"","finalize":"","libs":[{"var":"insidePolygon","module":"point-in-polygon"}],"x":290,"y":140,"wires":[["4ea1200cc07d1d5d"]]},{"id":"4ea1200cc07d1d5d","type":"debug","z":"d1395164b4eec73e","name":"debug 377","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":470,"y":140,"wires":[]}]
2 Likes

Me :grinning:

As E1cid says, not declaring variables was a hidden issue in JS before. It could cause unexpected issues. Also, the use of var is also not best practice, you should mostly be using const and let which don't "hoist" the variable definitions.

1 Like

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