Stuck with how to resolve this problem (Global context testing)

Ok, so I have this bit of code:

const dividor = 4;
const x = parseInt(global.get("SCAN_TIME")/dividor);
msg.payload = "start";
msg.delay = x;

Which works nice if the global is set.

So how to I catch it so if it isn't set, there is a default value?

eg:

const dividor = 4;
const x = parseInt(global.get("SCAN_TIME")/dividor);
if (x == undefined)
{
  x = 2000
}
msg.payload = "start";
msg.delay = x;

Not the best, but to show you what I am thinking.
I seem to be missing the trick to test the global context's condition.

Thanks in advance..

The usual way to apply a default value is like this

const scantime = global.get("SCAN_TIME") || 0

There is an alternative if the context variable might contain boolean false

const scantime = global.get("SCAN_TIME") ?? true

And then:

if (scantime == 0)
{
   scantime = place value here
}

sort of thing?

!!!

scantime can't be const as it will be changed if it is not set

Well I don't think you need that.

const scantime = global.get("SCAN_TIME") || place value here

Y-e-a-h b-u-t....
(not against you)

Say the value should be.... 20000
All things being good, the code loads and all is good with the world.

And I sorry now if I digress.

If it isn't set, I am wanting to have a default value that will get me there but also subtly indicate to me that the REAL value isn't set.
(This is kind of irrelevant but to put the cards on the table.)

Oh, and the SCAN_TIME can be altered via other systems.
So there is no FIXED value.

So if t isn't set, I make the value.... 15000

I don't know how the line would work:

cost scantime - global.get("SCAN_TIME") || 1500

if global.get("SCAN_TIME") is set to 20000 (or some other value.)

Again: Sorry. Does that make it clearer or just more confusing? :wink:

Ooooh!

Just tried what you said and it seems to work.
In an example function node.

I know you can't look in side my mind (the thought of that)
But I seem to be confused with what the || does with things.

Could you (maybe) help me learn?

Hmm Let's see if I understand well enough to explain. Probably not...

Consider this code

let nation = "Scotland"
if (nation === "England" || nation === "Scotland" || nation === "Wales") {
    nation = "Great Britain"
}

|| is the logical OR operator.
The if statement is evaluated left to right.

  1. Does nation equal "England"? No it doesn't, so on to the next test.
  2. Does nation equal "Scotland"? Yes it does. At least one test has succeeded.
    So the if test returns true without ever having to test "Wales"

In the global.get statement you imagine there are brackets around the right hand side
let scantime = (global.get("SCAN_TIME") || 100)

It means "Evaluate the code in brackets and use the result to set scantime"
And in brackets we have "Get the value of the global variable OR (if that fails) 100"

1 Like

Huge hugs.

I think that you actually found the problem with how I parsed it.

Somehow I was seeing the ( ) around both parts - as per you second example.

Thank you very much.

By the way, when using || to get a default value, it is almost always safer to use ?? Best to get into the habit now that everyone should be on node.js v18 or above.

Why is it almost always safer to use a nullish coalescing operator @TotallyInformation ?

Because if there is ever any possibility that the left-hand-side of the || might be either zero or Boolean false, it will not work as you expect. So you are in danger of getting a very hard to track-down bug.

The horridly named nullish coalescing operator ?? on the other hand only checks for null and undefined values, not for falsy values.

Hope that helps?

|| was designed as a Boolean OR operator and only later discovered to be quite handy for picking up default values.

2 Likes

So in summary as long as node.js is a recent version, I really should have suggested

global.set("SCAN_TIME", 0)
let scantime = global.get("SCAN_TIME") ?? 100 // with '||' this would return 100

or

global.set("unitsOfMeasure", "")
let units = global.get ("unitsOfMeasure") ?? "grams" // with '||' this would return "grams"

Because with || both 0 and empty string would evaluate as false and the default be wrongly applied.

2 Likes

yup. spot on. MDN explains these things well and lets you try it out in situ: Nullish coalescing operator (??) - JavaScript | MDN

1 Like

Wow!

Thanks that is a big wake up call for me.

Bad news though:
Just checked the 3 always on machine.

14.21.3
14.18.1
16.20.2

I think I have some catching up to do.

Quickly looking through my notes:
How do I force an update of node.js?

If you are using a Linux server based on Debian or a derivative, you can use Dave's update script.

Otherwise, depends on your platform. For Windows, the easiest is simply to re-install Node.js with the newer version unless you are using winget or similar.

For Linux, I prefer to use the semi-official install repo's.

Looks like Node.js have upped their game recently. They have a nice new page:

Remember to choose an LTS version though. The latest version isn't always the best.

Hmm, they seem to be recommending fnm which is a node.js version manager. Most of us don't like those since they cause confusion about installed packages typically. I'd stick with the installer for windows or a native package manager for Linux (there is a small link at the bottom of the page that takes you to those).

1 Like

RasPi Buster.

(Sorry, head down in something else just now)

I was sure I had this stuff written down somewhere.

The only update script I can find is this one:

##  Version 2:
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered)

# To also update node to the value given at the end.
bash <(curl -sL https://raw.githubusercontent.com/node-red/linux-installers/master/deb/update-nodejs-and-nodered) --node16

But nothing for node.js

That's Dave's script, it includes both Node-RED and Node.js.

Ok. Thanks.

They are running NR 3.0.1

That'll update them to 4.x and node .... 18 or 20?

I don't know how far these old RP3s will go.

They are the newer versions - luckily.

I think the script allows you to choose. Check the built-in help.

Ok. Thanks.

Sorry for being a stick in the mud

According to the comments at the top of the script, if you don't specify with --node18 or --node20, it will update to node.js18.

It looks like my Pies are all running node.js v20.