# Global numeric array trouble using global get and set

**URL:** https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732
**Category:** General
**Created:** [21 July 2018 21:34 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732 "2018-07-21T21:34:53Z")
**Posts on this page:** 20
**Page:** 2

<div class="post-metadata">

### Author: ![scargill](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/scargill/32/1118_2.png) [@scargill](https://discourse.nodered.org/u/scargill)
#### Post date: [22 July 2018 13:02 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/21 "2018-07-22T13:02:28Z")

</div>

I am doing just that and yes it WAS my understanding (though I’d forgotten) that strings and arrays should not need the final step as they aert pass by reference however I’m taking your advice and copying the local back to the global.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [22 July 2018 13:03 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/22 "2018-07-22T13:03:47Z")

</div>

> [@scargill](#):
>
> So normally I would work with globals directly…
> 
> if (global.get("manover")===0) global.set("manover",20);
> 
> But I can’t seem to do that with this numeric array but I can with a local copy (or maybe as Colin says it isn’t a copy but a reference?

Can you post the code that doesn't work so we can see?

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [22 July 2018 13:08 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/23 "2018-07-22T13:08:41Z")

</div>

> [@cflurin](#):
>
> I tried without global.set() and it doesnt' work!
> 
> ```auto
> var hum = global.get('hum') || [];
> 
> hum.unshift(msg.payload);
> hum.splice(24, 1);
> 
> ```

The array method unshift modifies the array itself, but splice does not, it returns the new array. So I was only half right anyway.

However, I agree with @knolleary that my suggestion is not good practice. I don't think my comment should be ignored as it is useful to understand how things work, but probably best not to do it that way anyway

---

<div class="post-metadata">

### Author: ![Andrei](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/andrei/32/10446_2.png) [@Andrei](https://discourse.nodered.org/u/Andrei)
#### Post date: [22 July 2018 13:19 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/24 "2018-07-22T13:19:43Z")

</div>

> [@Colin](#):
>
> The array method unshift modifies the array itself, but splice does not, it returns the new array. So I was only half right anyway.

As a matter of fact:

array.splice() - mutates the original array  
array.slice() - does not mutate the original array

I would go with pop() instead of splice / slice anyways

It works fine

```auto
[{"id":"d212e559.d6e8b8","type":"tab","label":"Array - Shift ","disabled":false,"info":""},{"id":"c0b39527.67aa38","type":"inject","z":"d212e559.d6e8b8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":0.1,"x":210,"y":180,"wires":[["2586acb.e0f4c54"]]},{"id":"2586acb.e0f4c54","type":"function","z":"d212e559.d6e8b8","name":"Set and display Global array","func":"let arr = [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23];\nglobal.set(\"garr\",arr);\nnode.warn(global.get(\"garr\"));\nreturn msg;","outputs":1,"noerr":0,"x":450,"y":180,"wires":[[]]},{"id":"c9a83478.a5dbb8","type":"inject","z":"d212e559.d6e8b8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":200,"y":300,"wires":[["2e7ca88c.dc6058"]]},{"id":"2e7ca88c.dc6058","type":"function","z":"d212e559.d6e8b8","name":"Shift Global array adding random value","func":"let rand = msg.payload%24;\n\n// read array from global, process and store againt o global\nlet arr = global.get(\"garr\");\narr.unshift(rand);\narr.pop();\nglobal.set(\"garr\",arr);\n\n// Display actual global array\nnode.warn(global.get(\"garr\"));\nreturn msg;","outputs":1,"noerr":0,"x":490,"y":300,"wires":[[]]},{"id":"da680b07.b8e498","type":"comment","z":"d212e559.d6e8b8","name":"Click inject node to shift array","info":"","x":250,"y":260,"wires":[]}]

```

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [22 July 2018 14:19 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/26 "2018-07-22T14:19:10Z")

</div>

> [@Andrei](#):
>
> array.splice() - mutates the original array  
> array.slice() - does not mutate the original array

Of course, brain fade setting in here I think.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [22 July 2018 14:25 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/27 "2018-07-22T14:25:40Z")

</div>

> [@Colin](#):
>
> var hum = global.get('hum') || ;  
> hum.unshift(msg.payload);  
> hum.splice(24, 1);

I would have expected that to work _except_ where 'hum' is not already setup. If the `|| []` is invoked then that does not set the global up so it will not work. Does it work if the global does contain an array? If not does it work if you add a global.set at the end?

---

<div class="post-metadata">

### Author: ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)
#### Post date: [22 July 2018 14:53 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/28 "2018-07-22T14:53:02Z")

</div>

> [@Colin](#):
>
> > [@Colin](#):
> >
> > var hum = global.get('hum') || ;  
> > hum.unshift(msg.payload);  
> > hum.splice(24, 1);
> 
> I would have expected that to work _except_ where 'hum' is not already setup. If the `|| []` is invoked then that does not set the global up so it will not work. Does it work if the global does contain an array? If not does it work if you add a global.set at the end?

Here is the flow I tested, actually it only doesn't work if the array is undefined. But I think `defensive programming` is anyway a good method so I 'd use global.set()

```auto
[{"id":"d6547d88.1430f","type":"inject","z":"12f1321f.454d1e","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":120,"wires":[["e8392f2d.46568"]]},{"id":"ea00bc55.eddb2","type":"debug","z":"12f1321f.454d1e","name":"","active":true,"tosidebar":false,"console":false,"tostatus":true,"complete":"payload","x":590,"y":120,"wires":[]},{"id":"e8392f2d.46568","type":"random","z":"12f1321f.454d1e","name":"","low":"20","high":"80","inte":"true","property":"payload","x":260,"y":120,"wires":[["ef4fe1a1.551f2"]]},{"id":"ef4fe1a1.551f2","type":"function","z":"12f1321f.454d1e","name":"hum array","func":"var hum = global.get('hum') || [];\n\nhum.unshift(msg.payload);\nhum.splice(24, 1);\n\n//global.set('hum', hum);\n\nmsg.payload=hum;\n\nreturn msg;","outputs":1,"noerr":0,"x":420,"y":120,"wires":[["ea00bc55.eddb2"]]}]

```

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [22 July 2018 15:27 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/29 "2018-07-22T15:27:25Z")

</div>

> [@cflurin](#):
>
> Here is the flow I tested, actually it only doesn't work if the array is undefined. But I think `defensive programming` is anyway a good method so I 'd use global.set()

I agree, but it is always good to understand why things do or don't work.

---

<div class="post-metadata">

### Author: ![shrickus](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/shrickus/32/517_2.png) [@shrickus](https://discourse.nodered.org/u/shrickus)
#### Post date: [23 July 2018 14:41 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/30 "2018-07-23T14:41:17Z")

</div>

> [@scargill](#):
>
> None of which explains why I can’t just work on the global array and miss out the local stage?

Pete, I think the confusion is because some of the array methods do not return the original array, but a new copy of the array, or even the _count_ of the new objects (a number) -- as mentioned on [this W3 Schools page](https://www.w3schools.com/js/js_array_methods.asp):

> The unshift() method adds a new element to an array (at the beginning), and "unshifts" older elements:
> 
> ```
> Example
> var fruits = ["Banana", "Orange", "Apple", "Mango"];
> fruits.unshift("Lemon"); // Adds a new element "Lemon" to fruits
> 
> ```
> 
> **The unshift() method returns the new array length.**

So it's best to use `global.get` to get a reference to the global array, then you can operate on it locally, and finally use `global.set` to "store" it back into the global space. As Nick mentioned, that also has the advantage of avoiding any side-effects once context persistence is no longer memory based.

I also had another thought, which might make sense for your specific case: you could add a named empty array to the functionGlobalContext section of your `settings.js` file. This would (I think) allow you to access the array from any function node (but not change nodes) in the the manner that you have been using. _I'm not saying that it's a good idea, but it could work_. It's just that this feels more like a configuration library array than a typical "global" runtime variable...

Nick, do you think that using functionGlobalContext for initial data storage is bad advice? Are there some potential issues with that idea?

---

<div class="post-metadata">

### Author: ![scargill](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/scargill/32/1118_2.png) [@scargill](https://discourse.nodered.org/u/scargill)
#### Post date: [23 July 2018 14:59 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/31 "2018-07-23T14:59:31Z")

</div>

Hi

I ended up using a local array updated from the global one and saving to the global at the end. That works and I’m happy with that, none of which explains why I could not do the maths directly on the global array.. I’ve done math on hundreds of global integers without needing a local copy. However as I didn’t keep the original global code I guess I’ll never find out what was wrong.

The somewhat badly named unshift method works a treat.

Pete

---

<div class="post-metadata">

### Author: ![dceejay](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/dceejay/32/38_2.png) [@dceejay](https://discourse.nodered.org/u/dceejay)
#### Post date: [23 July 2018 15:08 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/32 "2018-07-23T15:08:37Z")

</div>

Well there is push and pop that work on the end of an array, and shift and unshift that work on the front of an array so you can use whichever pair(s) makes most sense depending on which way you want to build your array.

---

<div class="post-metadata">

### Author: ![cflurin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/cflurin/32/29_2.png) [@cflurin](https://discourse.nodered.org/u/cflurin)
#### Post date: [23 July 2018 15:15 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/33 "2018-07-23T15:15:10Z")

</div>

> [@scargill](#):
>
> ...  
> I’ve done math on hundreds of global integers without needing a local copy.  
> ...

Did you use global.get() or just context.global.myvar?

---

<div class="post-metadata">

### Author: ![scargill](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/scargill/32/1118_2.png) [@scargill](https://discourse.nodered.org/u/scargill)
#### Post date: [23 July 2018 15:45 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/34 "2018-07-23T15:45:09Z")

</div>

Hi there

Unshift work a treat.. I don’t worry about resizing the local array as it gets recreated every time I call the function and I just use the first 24 values. The challenge of sticking with the global still alludes me. How would you use unshift with the GLOBAL array? Let’s say you were poking a global value into position zero…. If anyone is up for this challenge.. I have a local answer but it’s annoying the hell out of me that I can’t figure out how to do this with the global array.

Essentially it is a 24 value array. Every hour I need to unshift a value into position zero and resize the array to keep the length at 24 (hence reading the last 24 values. I read all 24 and divide by 24 to get the average humidity. A complication is that a few hours after the program starts there will not be 24 values so I need to use however many there are and divide by that number (the array on powerup is initialized to all values = -1).

I tried to do all of this on the original global array without using a local, and failed miserably.

Pete

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [23 July 2018 15:56 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/35 "2018-07-23T15:56:03Z")

</div>

> [@scargill](#):
>
> How would you use unshift with the GLOBAL array?

The only operations we provide are `get` and `set`. To modify a value in context you have to `get` it, modify it and then `set` it back. That's it.

Can you provide some code that shows (even if it doesn't work) what you think you want to be able to do?

---

<div class="post-metadata">

### Author: ![scargill](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/scargill/32/1118_2.png) [@scargill](https://discourse.nodered.org/u/scargill)
#### Post date: [23 July 2018 19:32 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/36 "2018-07-23T19:32:17Z")

</div>

Global.get and set, that is how I always use global vars

---

<div class="post-metadata">

### Author: ![scargill](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/scargill/32/1118_2.png) [@scargill](https://discourse.nodered.org/u/scargill)
#### Post date: [24 July 2018 07:42 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/38 "2018-07-24T07:42:23Z")

</div>

```auto
global.set(“blim”,[]);

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

```

It really doesn’t get any simpler. THAT much WORKS – Just done it. I set up the entire array with value -1 without issue, one part at a time.

However, adding in a little extra KILLS NODE-RED – the only way out is a reboot

```auto
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 + "]");

return msg;

```

---

<div class="post-metadata">

### Author: ![scargill](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/scargill/32/1118_2.png) [@scargill](https://discourse.nodered.org/u/scargill)
#### Post date: [24 July 2018 07:59 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/39 "2018-07-24T07:59:10Z")

</div>

When I say it works, it may actually do some damage as after all of the above I lost all my NR credentials. Thank heavens for backups.

---

<div class="post-metadata">

### Author: ![scargill](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/scargill/32/1118_2.png) [@scargill](https://discourse.nodered.org/u/scargill)
#### Post date: [24 July 2018 08:04 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/40 "2018-07-24T08:04:12Z")

</div>

As is becoming apparent, NR has no protection against abuse of global vars and apparently just gives up and dies when that happens.

I just gave an example that killed ny NR setup.

Pete

---

<div class="post-metadata">

### Author: ![knolleary](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/knolleary/32/3_2.png) [@knolleary](https://discourse.nodered.org/u/knolleary)
#### Post date: [24 July 2018 08:08 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/41 "2018-07-24T08:08:03Z")

</div>

> [@scargill](#):
>
> `for (a=0;a<10;a) global.set("blim[" + a + "]",-1);`

You killed Node-RED by not incrementing `a` in this for loop - causing it to loop forever.

---

<div class="post-metadata">

### Author: ![scargill](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/scargill/32/1118_2.png) [@scargill](https://discourse.nodered.org/u/scargill)
#### Post date: [24 July 2018 09:38 UTC](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732/42 "2018-07-24T09:38:39Z")

</div>

Oh, good grief – you are of course absolutely right Nick – my apologies. Ok that works. Back to how to unshift and pop

Hence below works except for the unshift line. I tried a couple of variations..

```auto
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);

//global.set("blim",global.get("blim.pop()"));

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

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

return msg;

```

[Previous page](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732.md?page=1)

[Next page](https://discourse.nodered.org/t/global-numeric-array-trouble-using-global-get-and-set/1732.md?page=3)
