Using node variables

Trying to do something that should be straight forward but missing something... basic, and the tutorials I am looking at I feel they are not using variables the way I am doing it in a node

For simplicity I have node where I need to define a starting value once and then increment it. I have it working this way:

On Start
this.testVar = 100

On Message
testVar = testVar + 1
msg = testVar
return msg;

This works but is global and I only want it to exist in the node, so I read, and it says do this:

On Start
(nothing)

On Message
var testVar = context.get('testVar') || 0
testVar = testVar + 1
msg = testVar
return msg;

But this doesn't work as it resets testVar to 0 on each pass (even though it says it shouldn't)

So how would I define a node variable on start, and then use it correctly as it runs?

Hi @mem16421

You are most there, you just need to write back the value (if its not already an object that is setup)

On Message

let testVar = context.get('testVar') || 0
testVar++
msg.payload = testVar
context.set('testVar', testVar) / * <--- Here */
return msg;

This is a function node then, and the scope of the context variable is just that node.
You are never saving the incremented testvar back to context.

var testVar = context.get('testVar') || 0  // Retrieve the con text variable, or else default to 0
testVar = testVar + 1                      // Increment
context.set('testVar', testVar)            // Save to context
msg = testVar                              // This is wrong. Should probably be msg.payload = testVar
return msg;

Note that you might have seen an example where a context variable holds an object

let car = context.get('car') || {"make": "ford", "model": "fiesta"}
car.model = "focus"

In this case the change will be saved if the variable exists, without an explicit context.set, though it's probably bad form to rely on that and not call context.set.

All up in my face @jbudd :rofl:

Once I starts to type I cannot be distracted...

@jbudd @marcus-j-davies

Thank you both!

So if I needed to set an initial value of 100 on testVar I could use On Start for that with a context.set(‘testVar’,100)?

or should On Start just not be used?

Yes, though I tend not to do that for simple cases like this. I tend to forget that On Start is there and when I look at the code in On Message it looks as if the context variable is not initialised, so I usually just use testVar let testVar = context.get('testVar') ?? 0

Note that nowadays let and const are preferred over var, google will tell you why if you are interested. Also the newer operator ?? is to be preferred over || in this situation as it specifically checks for null or undefined. Keep || for boolean expressions.

As far as I can recall I never use On Start for that or anything else.

It makes sense to me for the declaration of a variable to be visible in the same editor window as it's use.

Easy enough for you to try it and report back!

Edit - If you put context.set(‘testVar’,100) into On Start, every time a message arrives at the node, testVar will be set to 100, probably defeating the purpose of using a context variable - to save values from one message to the next.

I suppose you could do (not tested)

const foo = context.get('testVar') ?? 100
context.set('testVar', foo)

But I don't see the point.

I think the whole point of On Start is that it is only executed once, when the node is initially started.

On Message runs every time a message arrives.

Of course you are right.
I checked my test flow and I seem to have omitted the increment line.

Where's the dunce's hat emoji?

Thank you!