Indexing into flow/global scope array element using variable

I have a flow scoped array that I initialized like this:


Later on, I'm doing some processing to figure out which element of that array I want to make a change to. So I can do this if I want to change element [5] of that array.

flow.set('status[5]', msg.payload);

That works fine. But I actually want to use a variable instead of hard coding in the index value, so more like this:

flow.set('status[index_match]', msg.payload);

But node-red throws an error when I use a variable "index_match".

function : (error)"Error: Invalid property expression: unexpected i at position 7"

I can can kinda see why, a variable inside the single quotes is weird. Is there some other syntax for addressing an element of a flow scoped array? I'd rather not have to resort to this ugliness:

if (index_match == 0)
  flow.set('status[0]', msg.payload);
else if (index_match == 1)
 flow.set('status[1]', msg.payload);
else if (index_match == 2)
 flow.set('status[2]', msg.payload);

Edit: I also tried this syntax with the index outside the quotes.

flow.set('status'[index_match], msg.payload);

This runs, but doesn't actually change the array element, so doesn't do what I'm intending.

The key of the context functions is actually an expression evaluated by the runtime, it's behaves not like a map or dictionary. That is the reason why something like flow.set('status[5]', msg.payload); works in the first place.

Now if you do flow.set('status[index_match]', msg.payload);, the runtime evaluates status[index_match], but your local index_match variable is unknown to it. So it throws an error.

I see two possible solutions:

Get the status array from context and use it in your script like a normal array

let status = flow.get('status');
status[index_match] = msg.payload;

That will work because your array (or any object) is accessed by reference.


use a template string or string concatenation and build the string beforehand.

flow.set(`status[${index_match}]`, msg.payload);

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