Arithmetic operation [2362] error on one node-red but not other

Hello
I'm getting a javascript warnings when deploying on one Nodered but not another.

In it's most simplest form, the function code is as follows:

var temp = context.get("last_update"); //create a node variable
var current = new Date();  //capture the current date
msg.payload = current - temp;  //set the payload to the time date of the last update
context.set("last_update",current);  //save the node variable

(Obviously within the node I'm doing more, this is just for demonstration purposes)

On one NodeRed this Function compiles without warnings or errors.
But on my RPi-4 Node Red I get a warning about the line starting "msg.payload" saying:
"The workspace contains some nodes that are not properly configured"
"The left-hand side of an arithmetic operation must be of type 'any', 'number', 'bigint' or an enum type.(2362)"

Can anyone help?

Welcome to the forum @nzbaxterman.

The arithmetic expression in question is current - temp so the left hand side is current
current is a date object, not one of the permitted datatypes.
try current.getTime() - temp.getTime()

You might need to set a default value in your context.get statement too for the first time the function is run after a deploy
var temp = context.get("last_update") || new Date() might work.

This is caused by Monaco's Typescript engine being a numpty (something it excels at sadly).

The quickest fix is to declare the type:

const temp = context.get("last_update"); //create a node variable
/** @type {number} */
const current = new Date();  //capture the current date
msg.payload = current - temp;  //set the payload to the time date of the last update
context.set("last_update",current);  //save the node variable

Alternately, you could actually cast the date to a number:

const temp = context.get("last_update"); //create a node variable
const current = new Date();  //capture the current date
msg.payload = Number(current) - temp;  //set the payload to the time date of the last update
context.set("last_update",current);  //save the node variable

That also works but is a tiny bit more work for the node.

Also note that I've used const instead of var, you should ideally read up on the differences between var, let and const. The use of var is generally discouraged in JavaScript since it can lead to subtle bugs that are hard to track down.

And finally take note of jbudd's recommendation on the context.get line, it is best to give it a default just in case the variable is unset or something else that cannot be cast as a number. Though I would personally use the newer format:

const temp = context.get("last_update") ?? new Date()

Which will avoid issues should your context var ever contain zero.

Of course, defaulting to the current date/time might not be what you need and you might even want to wrap your code in an if so that it doesn't process if last_update is not yet set.

OK thanks - I now need to share more of the function node which throws the same compile warning:

This Deploys OK, but has the same warning:

var temp = context.get("last_update") || new Date();
var current = new Date();

if (temp!==undefined) {
    current = current.getTime() - temp.getTime();
    current = Math.floor(current/1000);
    msg.secsincelast = current;
    var minute = Math.floor(current/60);
    var hour = Math.floor(minute/60);
    var day = Math.floor(hour/24);
    if (current>=24*60*60) {
        msg.lastupdate = "Last update " + day + " days, " + hour%24 + " hours, " + minute%60 + " minutes, " + current%60 + " seconds ago";
    } else if (current>=60*60) {
        msg.lastupdate = "Last update " + hour%24 + " hours, " + minute%60 + " minutes, " + current%60 + " seconds ago";
    } else if (current>=60) {
        msg.lastupdate = "Last update " + minute%60 + " minutes, " + current%60 + " seconds ago";
    } else {
        msg.lastupdate = "Last update " + current%60 + " seconds ago";
    }
}

The editor complains because

var temp = context.get("last_update") || new Date();
var current = new Date();

At this point current is a Date object

if (temp!==undefined) {
    current = current.getTime() - temp.getTime();
    current = Math.floor(current/1000);

And here you are assigning an integer value to it (the difference in milliseconds)

If you were to change it to this it might work (not tested)

var temp = context.get("last_update") || new Date();
var current = new Date();

if (temp!==undefined) {
    var diff = current.getTime() - temp.getTime();
    diff = Math.floor(diff/1000);
    msg.secsincelast = diff;
    var minute = Math.floor(diff/60);
    var hour = Math.floor(minute/60);
    var day = Math.floor(hour/24);
    if (diff>=24*60*60) {
        msg.lastupdate = "Last update " + day + " days, " + hour%24 + " hours, " + minute%60 + " minutes, " + diff%60 + " seconds ago";
    } else if (diff>=60*60) {
        msg.lastupdate = "Last update " + hour%24 + " hours, " + minute%60 + " minutes, " + diff%60 + " seconds ago";
    } else if (diff>=60) {
        msg.lastupdate = "Last update " + minute%60 + " minutes, " + diff%60 + " seconds ago";
    } else {
        msg.lastupdate = "Last update " + diff%60 + " seconds ago";
    }
}

The same principals apply that I explained in my last post. Go through the code and either cast the dates to numbers or add @type comments and the "errors" will go away.

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