Global numeric array trouble using global get and set

@scargill the first argument you pass to get is the name of the property you want to get back from context.

Whilst you can include array-indexes in the name (such as blim[10]), you cannot include a javascript function in the name of the property and expect it to do anything. "blim.unshift(67)" is not a valid name for a property.

You need to get the property, then operate on it, then set it back.

global.set("blim",global.get("blim").unshift(67));

Also, please note that when sharing code in this forum, it is best to put ``` (three backticks) before and after your code sample so that it gets formatted properly. I've edited your previous post to add the backticks in.

I don't think it will work because unshift() returns the array length.

@cflurin d'oh you're right. There's no way to use unshift in a one-liner.

var blim = global.get("blim");
blim.unshift(67);
global.set("blim",blim);

One solution I tried and works:

if (!global.get('hum')) global.set('hum', []);

global.get('hum').unshift(msg.payload);
global.get("hum").splice(24, 1);

msg.payload = Math.round(global.get('hum').reduce(function(sum, a) {return sum + a}) / global.get('hum').length);

return msg;

The function returns the humidity average for the elements (1..24) in the array.

1 Like

I'm not the only one with slight difficulties with this, then. CFLURIN is right and that shows once and for all that you don't HAVE to use temporary local arrays if you don't want to. As you say a one liner is out but CFLURINs solution works - I made a minor change to pop instead of splice.

// set up
var a;
global.set("blim",[]);
for (a=0;a<10;a++) global.set("blim[" + a + "]",-1);

msg.payload="";
for (a=0;a<10;a++) msg.payload+="_ " + global.get("blim[" + a + "]");
node.send (msg);
// use every hour here with unnecessary debugging output s9o we know it works
var a;

global.get("blim").unshift(67);
global.get("blim").pop();

msg.payload="";
//for (a=0;a<11;a++) msg.payload+="_ " + global.get("blim[" + a + "]");
msg.payload=global.get("blim");
return msg;

Not sure whether it works so you add one element and remove the last. In my example the array can contain 1 to 24 elements. You don't need to initialise the array with -1.

As long as you full understand that when we introduce the Persistable Context feature in 0.19 and if you enable that feature, then because you are not doing a set anywhere, your code will not work.

Can you clarify that Nick - what won't work? Not initialising? If thats the case then yes I would expect to have to initialise the global array when NR powers up.

In 0.19 we introduce the ability to store context data. We will provide a File-based persistence with the 0.19 release. It provides two modes of operation. One is a caching mode - where all context is held in memory and updates are writing to disk in the background. The other mode is a non-caching mode where all gets/sets coming from the data on disk.

If you enable File Persistence the only way to update a value is by calling set. In its non-caching mode, doing a get will cause it to re-read the data from disk.

Lets say you have blim set to [1,2,3,4] stored in context.

If you do global.get("blim") you'll get the value [1,2,3,4] as expected

If you do global.get("blim").pop() you are not updating the value of blim stored on disk, so any subsequent call to global.get("blim") will still return [1,2,3,4].

As I've said quite a few times, the recommended way to update context values is:

  1. get a value
  2. change the value
  3. set the value back to context

Modifying context data in place is not the recommended pattern.

1 Like

Well, in this case to avoid the use of local var probably adding one line will do the job.

global.get('hum').unshift(msg.payload);
global.get("hum").splice(24, 1);
global.set('hum',global.get('hum')); // it doesn't fix the issue!

@scargill what's wrong with a local var? I always use a local var as @knolleary advised.

No.

Going back to my example, global.get("hum") will return [1,2,3,4] every time it is called in your example.

Aha, I see! I will change the post above.