# Changing global variable inside the function node

**URL:** <https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757>\
**Category:** General\
**Created:** [8 March 2019 22:21 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757 "2019-03-08T22:21:02Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![Petr](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/petr/32/6413_2.png) [@Petr](https://discourse.nodered.org/u/Petr)\
**Post date:** [8 March 2019 22:21 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/1 "2019-03-08T22:21:02Z")

</div>

I have global variable

> global.set("obed07", {payload: {template: "foo",Total:555, Today:0, Yesterday:0}});

How I can change it inside the function block. I am using following code now.

> ```
> var obed = global.get("obed07"); 
> obed.payload.template="bar";
> global.set("obed07",obed);
> 
> ```

Is there some other, more direct way (one line of the code) to achieve this?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [9 March 2019 16:20 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/2 "2019-03-09T16:20:51Z")

</div>

Not really, that's about as good as it gets. There are ways to reduce that down by a line but it would be hard to follow - really not worth it. JavaScript is actually very good at optimising things like this when it actually runs so I wouldn't worry about it.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [9 March 2019 16:27 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/3 "2019-03-09T16:27:52Z")

</div>

Have you tried...

```auto
global.get("obed07").payload.template="bar";

```

Then inspected the context side bar to see if it works?

Obviously the item will need to be present in global context 1st.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [9 March 2019 16:31 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/4 "2019-03-09T16:31:10Z")

</div>

That won't work as it doesn't actually update the variable.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [9 March 2019 16:39 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/5 "2019-03-09T16:39:18Z")

</div>

I wasn't sure if an object reference was returned & thus updatable directly. Can't get my head around this one. I'm certain I've done something similar?!?

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [9 March 2019 16:42 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/6 "2019-03-09T16:42:57Z")

</div>

> [@Steve-Mcl](#):
>
> I wasn't sure if an object reference was returned & thus updatable directly. Can't get my head around this one. I'm certain I've done something similar?!?

Drat! It does work actually.

However, I'm far from convinced that isn't the intended outcome. Let me read the docs again.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [9 March 2019 16:47 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/7 "2019-03-09T16:47:04Z")

</div>

As I thought, the docs are clear about this - you should be using `set` to update the variable. I think that means that the approach you've given is an unintended outcome and so couldn't be relied upon.

However, we really need "official" input from @knolleary or @dceejay.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [9 March 2019 16:47 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/8 "2019-03-09T16:47:59Z")

</div>

yeah I just did a sanity check & I was right 😛

I believe it is perhaps not the intention however a side affect of the Javascript language. The global/flow get() functions return the object & thus its a reference (not a copy) & therefore modifiable.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [9 March 2019 16:50 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/9 "2019-03-09T16:50:28Z")

</div>

> [@Steve-Mcl](#):
>
> I believe it is perhaps not the intention however a side affect of the Javascript language. The global/flow get() functions return the object & thus its a reference (not a copy) & therefore modifiable.

Not only would I not want to rely on that but I also think that it is much harder to follow - coming back to it in 6m time I think it might take a while to work out. Certainly if, for some reason, the documented approach is enforced, it might be difficult to spot an debug.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [9 March 2019 16:55 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/10 "2019-03-09T16:55:10Z")

</div>

I am certainly no expert in all things javascript however I can see no way this could be prevented or broken for that matter. When you store an object (where ever that is) you ultimately store a reference & thus retrieve a reference. If it wasn't, you'd be setting/getting a clone/copy & then this would be a whole new problem (deep vs shallow copy).

Note: I'm not advocating this approach (its certainly less readable to those unaware of the subtleties of javascript. the `get` `set` functions are far clearer in their intent.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [9 March 2019 16:57 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/11 "2019-03-09T16:57:03Z")

</div>

PS, for anyone reading this, i suspect it will ONLY work for objects / arrays - i.e. wont work for strings/numbers or any other immutable.

---

<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:** [9 March 2019 16:58 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/12 "2019-03-09T16:58:24Z")

</div>

Depending on the implementation of the storage plugin it will probably break. Most likely with any non-memory based context storage.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [9 March 2019 17:02 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/13 "2019-03-09T17:02:20Z")

</div>

oh yes - didnt think of that.

However, it depends how the storage mechanism works. If i were to write it, the store would primarily be memory based (writing to file when property is updated, but only reading only upon node-red startup) in which case it would still work.

But yes, as @TotallyInformation, said, probably best to avoid.

---

<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:** [9 March 2019 17:06 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/14 "2019-03-09T17:06:58Z")

</div>

well we don't mind if you wish to bend the rules as long as you are happy knowing the consequences, but probably best not to encourage others to do so if they are unaware of the gotchas.

---

<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:** [9 March 2019 17:07 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/15 "2019-03-09T17:07:41Z")

</div>

> [@Steve-Mcl](#):
>
> However, it depends how the storage mechanism works. If i were to write it, the store would primarily be memory based (writing to file when property is updated, but only reading only upon node-red startup) in which case it would still work

Except the update would not get written to disk and would be lost when Node-RED restarts. Not exactly the idea of a persistent context.

You need to call .set so the context storage plugin know it has something to save.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [9 March 2019 17:11 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/16 "2019-03-09T17:11:49Z")

</div>

> [@knolleary](#):
>
> Except the update would not get written to disk and would be lost when Node-RED restarts. Not exactly the idea of a persistent context.

And theres the silver bullet 🙂

Of course you are correct for a file based store. The functions would need to be executed.

@Petr by now hopefully you will see although yes, you can update in one line, should you ever use file back context or the implementation of get/set change, you may have problems. Stick with what you have 🙂 unless you fully understand the what and the why

---

<div class="post-metadata">

**Author:** ![Petr](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/petr/32/6413_2.png) [@Petr](https://discourse.nodered.org/u/Petr)\
**Post date:** [10 March 2019 12:08 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/17 "2019-03-10T12:08:20Z")

</div>

Guys, you are great here! Thanks  
I didn’t intended to go so deep 😃  
For me (as a Pythonist, who is trying to taste js soup now) it is difficult to accept 3 lines of the code and all those curly and semicolon things. But I am trying to work hard and to accept this "new different culture" 😃

I was thinking about to change the property of the global object directly, without the necessity to:

- declare variable
- call the whole object to the script node as a local object
- changing the property of the local object
- returning local object back to the global variable.  
BTW, It looks to me, I am rewriting/resetting the whole object stored inside the global variable instead of rewriting property value only.

I was really thinking about some semantic like you see below, and, of course, trying to find some examples, I was not successful (yes, it was a long night lol)

```auto
global.set("obed07").payload.template = "bar";
global.set("obed07".payload.template:"bar");
global.set("obed07.payload.template":"bar");

// for the readers of this forum
// this is an example of the BAD syntax, dont use it

```

Thank you again for explanation.  
BTW: how often / in which cases to use global variables? I have a small project managing 10 Sonoff mqtt POW R2 switches and I need to keep the recent state of each switch and compare it with new values from the incoming mqtt flow . Till now, the only way I have found for this is to use globals.

---

<div class="post-metadata">

**Author:** ![TotallyInformation](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/totallyinformation/32/31_2.png) [@TotallyInformation](https://discourse.nodered.org/u/TotallyInformation)\
**Post date:** [10 March 2019 13:52 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/18 "2019-03-10T13:52:06Z")

</div>

> [@Petr](#):
>
> For me (as a Pythonist, who is trying to taste js soup now) it is difficult to accept 3 lines of the code and all those curly and semicolon things. But I am trying to work hard and to accept this "new different culture" 😃

Haha, well that cuts both ways. I learned Python long before I learned JavaScript. In fact it was where I first really understood about object-based programming. Sadly, the Python masters completely missed some important developments in the world and that meant that Python was never integrated as well into the web world. At the same time, Node.JS came along which meant that, as a non-pro programmer, I chose a single language to cover both front- and back-end programming. Bye-bye PHP and Python (and PERL!) - I've only so much time to try and remember how to do things.

I don't like all the `{};` stuff either - in fact I refuse to use `;` unless they are absolutely necessary (only about 3 use cases in JavaScript that actually need a `;`).

> [@Petr](#):
>
> global.set("obed07.payload.template":"bar");

Argh! I keep forgetting that this is actually possible!!! That works absolutely fine 😄

Except that you just got one thing slightly wrong, here is the correct answer (colons are for objects, comma's for function arguments):

```
global.set("obed07.payload.template","bar")

```

This also works in case you are wondering:

```
flow.set("obed07.payload['template']","jim")

```

---

<div class="post-metadata">

**Author:** ![Petr](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/petr/32/6413_2.png) [@Petr](https://discourse.nodered.org/u/Petr)\
**Post date:** [10 March 2019 15:07 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/19 "2019-03-10T15:07:56Z")

</div>

Aaaa.... so no more 3 lines of code?  
Is it really possible to change the property of the global variable in the one line of code within the function code? No need to define, get, change, set? Just set directly?

What about the second syntax?

```auto
flow.set("obed07.payload['template']","jim")

```

What do the square brackets mean? I don’t understand it.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [10 March 2019 15:48 UTC](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757/20 "2019-03-10T15:48:20Z")

</div>

> [@Petr](#):
>
> What about the second syntax?
> 
> ```auto
> flow.set("obed07.payload['template']","jim")
> 
> ```
> 
> What do the square brackets mean? I don’t understand it

It's for accessing properties of an object  
E.g object.prop and object["prop"] are the same. Means you can dynamically access properties of an object.

[Next page](https://discourse.nodered.org/t/changing-global-variable-inside-the-function-node/8757.md?page=2)
