# Error or bug with global get when undefined

**URL:** <https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711>\
**Category:** General\
**Created:** [7 February 2019 13:30 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711 "2019-02-07T13:30:28Z")\
**Posts on this page:** 15\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lost](https://avatars.discourse-cdn.com/v4/letter/l/22d042/32.png) [@Lost](https://discourse.nodered.org/u/Lost)\
**Post date:** [7 February 2019 13:30 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/1 "2019-02-07T13:30:28Z")

</div>

Hi.

When i am trying to get a global variable with function  
`TotkWh = global.get("power.VK.gang.kWh.Total")||0;`  
i get this error:  
`function : (error) "TypeError: Cannot read property 'VK' of undefined"`

If i write it without `.` like this it works:  
`TotkWh = global.get("powerVKgangkWhTotal")||0;`

i am using `||0` to get a 0 for the first read when it is undefined.

Is this a bug or am i using the wrong function?

Yes i know i can write it without `.` but i want it with it.

Here is the flow i am trying to write.

> **Flow**
>
> `[{"id":"d0bcb4c3.860368","type":"inject","z":"f841627a.c1e92","name":"","topic":"","payload":"ON","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":100,"wires":[["6d88067f.f655e8"]]},{"id":"6a2a8908.b6a448","type":"inject","z":"f841627a.c1e92","name":"","topic":"","payload":"OFF","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":150,"y":140,"wires":[["6d88067f.f655e8"]]},{"id":"a7fa44ca.2f3708","type":"comment","z":"f841627a.c1e92","name":"Floorheat","info":"","x":100,"y":60,"wires":[]},{"id":"5ca1fa09.178854","type":"power-monitor","z":"f841627a.c1e92","name":"VKgang","threshold":0,"startafter":1,"stopafter":1,"x":400,"y":120,"wires":[[],["5041b7d7.f4d068","7a26ef14.03737"]]},{"id":"6d88067f.f655e8","type":"function","z":"f841627a.c1e92","name":"Watt","func":"if (msg.payload == \"ON\"){\n msg.payload = 5000\n}\n else {\n msg.payload = 0\n }\nreturn msg;","outputs":1,"noerr":0,"x":270,"y":120,"wires":[["5ca1fa09.178854"]]},{"id":"5041b7d7.f4d068","type":"debug","z":"f841627a.c1e92","name":"Stop event","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","x":570,"y":180,"wires":[]},{"id":"7a26ef14.03737","type":"function","z":"f841627a.c1e92","name":"Save","func":"//Get global kwh\nTotkWh = global.get(\"power.VK.gang.kWh.Total\")||0;\nDaykWh = global.get(\"power.VK.gang.kWh.Day\")||0;\nWeekkWh = global.get(\"power.VK.gang.kWh.Week\")||0;\nMonthkWh = global.get(\"power.VK.gang.kWh.Month\")||0;\nYearkWh = global.get(\"power.VK.gang.kWh.Year\")||0;\n\n//Calculate and add new power usage to kWh\nTotnewkwh = TotkWh + msg.payload.energy;\nDaynewkwh = DaykWh + msg.payload.energy;\nWeeknewkwh = WeekkWh + msg.payload.energy;\nMonthnewkwh = MonthkWh + msg.payload.energy;\nYearnewkwh = YearkWh + msg.payload.energy;\n\n//Save newkwh to global\nglobal.set(\"power.VK.gang.kWh.Total\",Totnewkwh);\nglobal.set(\"power.VK.gang.kWh.Day\",Daynewkwh);\nglobal.set(\"power.VK.gang.kWh.Week\",Weeknewkwh);\nglobal.set(\"power.VK.gang.kWh.Month\",Monthnewkwh);\nglobal.set(\"power.VK.gang.kWh.Year\",Yearnewkwh);\n\nreturn msg;","outputs":1,"noerr":0,"x":550,"y":120,"wires":[["2a7a781b.971438"]]},{"id":"2a7a781b.971438","type":"debug","z":"f841627a.c1e92","name":"Saved","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":690,"y":120,"wires":[]}]`

It is for calculating the accumulated power use of my floorheat cables. Using the `node-red-contrib-power-monitor` node. I get an input event when it goes off and on and i know the Watt for the cable.

Thanks.

---

<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:** [7 February 2019 15:19 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/2 "2019-02-07T15:19:10Z")

</div>

I can confirm that one cannot have `.` in a context variable name, and I can imagine why. Whether that is a documented feature, an undocumented feature or a bug I don't know. There are probably a number of other characters that are not legal also.

---

<div class="post-metadata">

**Author:** ![Lost](https://avatars.discourse-cdn.com/v4/letter/l/22d042/32.png) [@Lost](https://discourse.nodered.org/u/Lost)\
**Post date:** [7 February 2019 15:27 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/3 "2019-02-07T15:27:27Z")

</div>

It works fine as long as it is defined first.

Se this flow:

> **Flow**
>
> `[{"id":"3bce3fa7.489d4","type":"function","z":"f841627a.c1e92","name":"Save","func":"global.set(\"power.VK.gang.kWh.Total\",555)\nreturn msg;","outputs":1,"noerr":0,"x":290,"y":400,"wires":[["a6870b51.0a0d18"]]},{"id":"6f924b72.354dc4","type":"function","z":"f841627a.c1e92","name":"read","func":"msg.TotkWh = global.get(\"power.VK.gang.kWh.Total\")||0;\nreturn msg;","outputs":1,"noerr":0,"x":290,"y":340,"wires":[["d8e625c9.e5f408"]]},{"id":"7d51ee19.8cf72","type":"inject","z":"f841627a.c1e92","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":400,"wires":[["3bce3fa7.489d4"]]},{"id":"738ea82a.e6c888","type":"inject","z":"f841627a.c1e92","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":160,"y":340,"wires":[["6f924b72.354dc4"]]},{"id":"a6870b51.0a0d18","type":"debug","z":"f841627a.c1e92","name":"Save","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":410,"y":400,"wires":[]},{"id":"d8e625c9.e5f408","type":"debug","z":"f841627a.c1e92","name":"Read","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":410,"y":340,"wires":[]}]`

If you read it gets error. If you save it saves. And now you can read. So it is only the `||0` that is not working as expected.

Thanks

---

<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:** [7 February 2019 15:49 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/4 "2019-02-07T15:49:28Z")

</div>

I don't think it is the `|| 0` that is failing, it is the `context.get("a.b.c")` where it has not previously been set with `context.set`

---

<div class="post-metadata">

**Author:** ![JayDickson](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/jaydickson/32/90592_2.png) [@JayDickson](https://discourse.nodered.org/u/JayDickson)\
**Post date:** [7 February 2019 15:59 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/5 "2019-02-07T15:59:17Z")

</div>

Your get would work if your "power" variable is an object with a nested property structure. Your undefined result is saying that the function is looking for a property that doesn't exist, leading me to suspect you're not storing as an object.

---

<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:** [7 February 2019 16:12 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/6 "2019-02-07T16:12:09Z")

</div>

Power isn't a variable when used like this (or at least it shouldn't be, I don't think), it is a string that happens to have dots in it. Having said that I haven't examined the docs for context.set/get. Not at pc at the moment.

---

<div class="post-metadata">

**Author:** ![Lost](https://avatars.discourse-cdn.com/v4/letter/l/22d042/32.png) [@Lost](https://discourse.nodered.org/u/Lost)\
**Post date:** [7 February 2019 16:12 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/7 "2019-02-07T16:12:31Z")

</div>

Ok.

> [@Colin](#):
>
> I don't think it is the `|| 0` that is failing, it is the `context.get("a.b.c")` where it has not previously been set with `context.set`

Is there another way i can easy check if it exist or have been set and if not set it to 0?

> [@JayDickson](#):
>
> Your get would work if your "power" variable is an object with a nested property structure. Your undefined result is saying that the function is looking for a property that doesn't exist, leading me to suspect you're not storing as an object.

If i save it first it is saved as an object i think? check screenshot:

 ![Save](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/d/d2a590051c687cd1135f40f6f6c727557cbd148f.jpeg)  
I now can use a global.get command and my flow works fine. But if i restart the pi and the variables are empty it does not work anymore and i have to set them to 0 again. I tought that by adding `|| 0` it would add it to 0 if it does not exist. It does this if i dont have any `.` in the variable name.

---

<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:** [7 February 2019 16:19 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/8 "2019-02-07T16:19:06Z")

</div>

I' m using an object called `state` and store it to a global variable.

But I first get/set the whole object:

```auto
global.set('state', state);
var state = global.get('state');
...
var value = state.value;

```

---

<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:** [7 February 2019 16:26 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/9 "2019-02-07T16:26:17Z")

</div>

A context variable name must be a valid JavaScript identifier.

That means it cannot have dots in its name, nor can it have `[` `]` - and I'm sure some other punctuation.

When you do `context.get('parts.foo')` we will look up the context variable called `parts` and return its `foo` property.

If `parts` doesn't exist, then `parts.foo` will not exist.

In Node-RED 0.19.5:

- `flow.get('parts.foo')` will return `undefined`
- `global.get('parts.foo')` will throw the error seen in the original post.

This difference in behaviour is a bug that has been fixed in 0.20. They now _both_ return `undefined`.

The code:

```auto
var foo = flow.get('parts.foo') || 0

```

will set `foo` to `0` if `flow.get('parts.foo')` returns a false-like value (undefined, `0`, `false` `""` etc). But that is just setting the local variable - it doesn't change what is in context.

So @Lost, what you are trying to do will work once we release 0.20.0. Whilst you are on 0.19.5, you can either switch to `flow` context rather than `global` to avoid the bug, or wrap it in a try/catch block.

---

<div class="post-metadata">

**Author:** ![Lost](https://avatars.discourse-cdn.com/v4/letter/l/22d042/32.png) [@Lost](https://discourse.nodered.org/u/Lost)\
**Post date:** [7 February 2019 16:41 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/10 "2019-02-07T16:41:59Z")

</div>

Thanks knolleary for the detailed responce.

Here is what i am running and can confirm that it works as expected if i run it as a flow variable istead of a global.  
 ![function](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/1/15f3a4b107a361fce26f300b0664ae509c597f91.jpeg)  
Will just use the flow variable and move everything to same flow for now until 0.20.0 as i dont know how to wrap it in a try/catch block.

Thanks.

---

<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:** [7 February 2019 16:44 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/11 "2019-02-07T16:44:32Z")

</div>

> [@Lost](#):
>
> as i dont know how to wrap it in a try/catch block.

No problem - glad you got it working. Just so you know, the try/catch block method would look like:

```javascript
var TotkWh;
try {
   TotkWh = global.get("power.VK.gang.kWh.Total")
} catch(err) {
   // an error has been thrown - ignore it and move on
   TotkWh = 0;
}

```

---

<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:** [7 February 2019 17:12 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/12 "2019-02-07T17:12:39Z")

</div>

though in general it's usually best to try to keep the scope of variables as small as possible (i.e. prefer local (inside a function) - then flow - then global) to help avoid name clashes etc when you copy things around.

---

<div class="post-metadata">

**Author:** ![Lost](https://avatars.discourse-cdn.com/v4/letter/l/22d042/32.png) [@Lost](https://discourse.nodered.org/u/Lost)\
**Post date:** [7 February 2019 22:37 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/13 "2019-02-07T22:37:51Z")

</div>

> [@knolleary](#):
>
> Just so you know, the try/catch block method would look like:

Wow thanks @knolleary that worked.

Bit of topic but is it possible to save a variable to a file from a function node simular to saving to global variable? Would be handy to have some variables restart proof. I know i can change so that all the variables goes to a file instead of ram but would be nice to be able to save some variables to file and some to ram from the function node.

Edit: Never mind just found `https://github.com/node-red/node-red/wiki/Design:-Persistable-Context` so will study that as i think it will do what i want.

Thanks

---

<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:** [7 February 2019 22:58 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/14 "2019-02-07T22:58:19Z")

</div>

That's the internal development design doc. The user docs for context are here: [https://nodered.org/docs/user-guide/context](https://nodered.org/docs/user-guide/context)

---

<div class="post-metadata">

**Author:** ![zenofmud](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/zenofmud/32/316_2.png) [@zenofmud](https://discourse.nodered.org/u/zenofmud)\
**Post date:** [8 February 2019 00:16 UTC](https://discourse.nodered.org/t/error-or-bug-with-global-get-when-undefined/7711/15 "2019-02-08T00:16:50Z")

</div>

You can also read [A guide to understanding 'Persistent Context'](https://discourse.nodered.org/t/a-guide-to-understanding-persistent-context/4115/60)
