# No periods in context variable names?

**URL:** <https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269>\
**Category:** General\
**Created:** [31 August 2020 19:50 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269 "2020-08-31T19:50:41Z")\
**Posts on this page:** 17\
**Page:** 1

<div class="post-metadata">

**Author:** ![Nodi.Rubrum](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodi.rubrum/32/107482_2.png) [@Nodi.Rubrum](https://discourse.nodered.org/u/Nodi.Rubrum)\
**Post date:** [31 August 2020 19:50 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/1 "2020-08-31T19:50:42Z")

</div>

Not sure why I have not seen this before, but I was writing a flow that need use of context, so I did the following... Where msg.topic just happened to be FQDN reference, say [www.google.com](http://www.google.com).

```auto
var theDevice = flow.get(msg.topic) || {};

theDevice.ping = msg.payload;

if (typeof theDevice.exclude === undefined)
    theDevice.exclude = false;

flow.set(msg.topic, theDevice);

return msg;

```

When I looked at the context, I found...  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/c/0/c063a9b1f84a43102d93512bbdde55671b6968ad.png)

I don't yet have a lot of experience with JS, but I take it somewhere there is a rule that says periods can't be part of a variable name, because they are parsed as part of the property (tree). But why is context doing this when context requires a string?

For example, you do flow.get('somestring') or flow.set('somestring', theValue). If 'somestring' has a period in it... that should not be an issue. It is a string, not a variable. Or is this a case where I have to do `$(msg.topic}` to avoid the parsing? That did not work either.

Of course I then tried a literal string flow.set('[www.google.com](http://www.google.com)'), and that also was parsed, IMHO that just does not make sense at face value, JS variable rules not withstanding. So is this something unique to JS? Or even NR? What if I really want a flow reference label to have a period in it? Is that not possible, or such?

Of course an object property key can have a period in it, for example "[www.google.com](http://www.google.com): true" can be done. Even { "[www.google.com](http://www.google.com)": { "[www.microsoft.com](http://www.microsoft.com)": false, "[red.hat.com](http://red.hat.com)": true} } can be done.

For example...

```auto
theDevice['this.is.a.test']='test';
var theTest = theDevice['this is a test'];

```

The above shows up as 'this.is.a.test': 'test' in context.

---

<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:** [31 August 2020 20:22 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/2 "2020-08-31T20:22:56Z")

</div>

Context variable names should be valid JavaScript identifiers.

This is because you can do things like this:

```auto
var myObject = { "foo": 1, "bar": 2 };
flow.set("test", myObject);

// Get individual values
var foo = flow.get("test.foo");
var bar = flow.get("test.bar");

// Update just bar:
flow.set("test.bar", 3);

```

It also works with arrays:

```auto
var myArray = [1,2,3,4];
flow.set("test", myArray);

var firstElement = flow.get("test[0]");
var secondElement = flow.get("test[1]");

flow.set("test[2]", 10);
```

---

<div class="post-metadata">

**Author:** ![Nodi.Rubrum](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodi.rubrum/32/107482_2.png) [@Nodi.Rubrum](https://discourse.nodered.org/u/Nodi.Rubrum)\
**Post date:** [31 August 2020 20:27 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/3 "2020-08-31T20:27:40Z")

</div>

So this was by design, which is cool. I just had not tripped over it as yet. It means my flow either creates some funky dot noted trees... which work but are not needed, or I change the logic to not use FQDN as 'keys' as I thought I would.

---

<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:** [1 September 2020 10:27 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/4 "2020-09-01T10:27:24Z")

</div>

If you read up on JavaScript identifiers, you will find that you _can_ use periods. However, it complicates matters. That's because you can no longer refer to your property using dotted naming.

```auto
const odd = { "normal": 1, "not.normal": 2 }

console.log( odd.normal ) // This works just fine
console.log( odd.not.normal ) // This does not work
console.log( odd["not.normal"] ) // But this does work

```

---

<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:** [1 September 2020 14:18 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/5 "2020-09-01T14:18:05Z")

</div>

I see that is is possible to have embedded dots in property names, but I can't see how to define a variable name with a dot. This does not seem to be valid, according the editor.  
`var odd.name = 2`  
However I can't find any reference that says it is not valid in variable names.

---

<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:** [1 September 2020 14:46 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/6 "2020-09-01T14:46:35Z")

</div>

`var`s end up in `global` in node (`window` in browser)

so to have a var of "odd.name" you need to use bracket notation.

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/0/0/008a93be5df68fe5479cb6dacd7d693ac459836c.png)

---

<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:** [1 September 2020 14:48 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/7 "2020-09-01T14:48:26Z")

</div>

> [@TotallyInformation](#):
>
> If you read up on JavaScript identifiers, you will find that you _can_ use periods.

If you really want to get into the fine detail, you have to dig into the ECMAScript spec - [ECMAScript 2015 Language Specification – ECMA-262 6th Edition](https://ecma-international.org/ecma-262/6.0/#sec-object-initializer)

And you have to get a bit more precise on terminology.

```auto
var myObject = { myProperty: 123 }

```

Here, `myObject` is an _identifier_ and `myProperty` is a _property_.

The rules are different for what is a valid _identifier_ and what is a valid _property_.

### Identifier:

> In ES2015, identifiers must start with `$` , `_` , or [any symbol with the Unicode _derived core property_`ID_Start`](https://codepoints.net/search?IDS=1).  
> The rest of the identifier can contain `$` , `_` , [U+200C zero width non-joiner](https://codepoints.net/U+200C), [U+200D zero width joiner](https://codepoints.net/U+200D), or [any symbol with the Unicode _derived core property_`ID_Continue`](https://codepoints.net/search?IDC=1).

### Property:

> A property name can be either an _identifier name_ (i.e. identifiers + reserved words), a _string literal_ , or a _numeric literal_ .

This means it is perfectly valid to have `.` in a _property_ name, as long as it is written as a _string literal_ - ie with surrounding quotes of some type.

But you cannot have a `.` in a top-level _identifier_.

This post gives a lot more detail (and is where I copied the extracts above from): [Valid JavaScript variable names in ES2015 · Mathias Bynens](https://mathiasbynens.be/notes/javascript-identifiers-es6)

---

<div class="post-metadata">

**Author:** ![Nodi.Rubrum](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodi.rubrum/32/107482_2.png) [@Nodi.Rubrum](https://discourse.nodered.org/u/Nodi.Rubrum)\
**Post date:** [1 September 2020 15:49 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/8 "2020-09-01T15:49:40Z")

</div>

Which takes this full circle... in effect, 'reference' (using the term loosely) names do not follow the same 'rules' as variables. Which is fine, it just is not intuitive when context references could be seen as 'references', but are in effect 'structured' variables. This is reasonable in the fact that referencing context is done by a string literal typically. But as was noted above, that is not the only use case, in that said string is parsed as a variable, i.e. variable with or without property reference(s). Thus '[www.google.com](http://www.google.com)' is not a literal per the context parsing. but a variable with properties, such that on context it is really www-\>google-\>com = whatever. Even when I did bracket the string literal in some type of quotes, it was still parsed. I don't recall from memory is this documented as such? But as a new to JS, if not NR, this did trip me up until I realized what the context parsing was doing.

---

<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:** [1 September 2020 16:03 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/9 "2020-09-01T16:03:33Z")

</div>

I think that it is documented but yes, it _is_ very confusing even for experienced programmers.

However, the fact that you can use periods and other characters in property names can be really useful and can save a whole bunch of programming - for example, when making use of MQTT topics with "/" as the typical level separator and storing them in Node-RED as properties.

It is also nice that Node-RED's global/flow/context variable getter and setter work with those complex property names. Inevitably however, the written code gets a bit confusing. Rather like when you mix JavaScript code into HTML attributes when using Angular, Vue or REACT and you have to nest quotes.

---

<div class="post-metadata">

**Author:** ![Nodi.Rubrum](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodi.rubrum/32/107482_2.png) [@Nodi.Rubrum](https://discourse.nodered.org/u/Nodi.Rubrum)\
**Post date:** [1 September 2020 16:12 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/10 "2020-09-01T16:12:36Z")

</div>

Oh, I am not suggesting anything or such, the flexibility is good, it is just a surprising result when you have done 100 string literals, that did not happen to have a period in the string, to do such, and see the context variable parsed as noted. My initial reaction was, 'What the hell is this?' I happened to say in English, so my dachshunds pretty much ignored it. But when I later said 'Das ist einfach nicht richtig' the dachshunds looked at me, as if to say 'Was zum Teufel'. Translation [That is just not right] [What the heck (hell, devil)].

---

<div class="post-metadata">

**Author:** ![Nodi.Rubrum](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodi.rubrum/32/107482_2.png) [@Nodi.Rubrum](https://discourse.nodered.org/u/Nodi.Rubrum)\
**Post date:** [1 September 2020 16:15 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/11 "2020-09-01T16:15:39Z")

</div>

And this concludes the German language lesson for today. [OTFL][

---

<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:** [1 September 2020 19:01 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/12 "2020-09-01T19:01:15Z")

</div>

Never hurts to have a language lesson 🙂 Sadly my German goes as far as ordering the beers and a few other basics that are required for skiing in Switzerland.

---

<div class="post-metadata">

**Author:** ![ristomatti](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ristomatti/32/5857_2.png) [@ristomatti](https://discourse.nodered.org/u/ristomatti)\
**Post date:** [1 September 2020 19:41 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/13 "2020-09-01T19:41:25Z")

</div>

> [@Nodi.Rubrum](#):
>
> ```auto
> var theDevice = flow.get(msg.topic) || {};
> ... 
> flow.set(msg.topic, theDevice);
> 
> ```

You should be able to work around the issue by using a container object it the context. Something like:

```auto
var devices = flow.get('devices') || {};
var theDevice = devices[msg.topic] || {};
... 
devices[msg.topic] = theDevice;
flow.set('devices', devices);

```

It's not the same thing as you'll retrieve the reference to the container containing all the devices instead of only one but I doubt it will have (nearly) any performance implications.

---

<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:** [1 September 2020 19:47 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/14 "2020-09-01T19:47:47Z")

</div>

> [@ristomatti](#):
>
> You should be able to work around the issue by using a container object it the context.

Yup - adding a top level object would work - and the flow.set/get statements can be streamlined to:

```auto
flow.set(`devices["${msg.topic}"]`) = 'hello there';

```

---

<div class="post-metadata">

**Author:** ![ristomatti](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/ristomatti/32/5857_2.png) [@ristomatti](https://discourse.nodered.org/u/ristomatti)\
**Post date:** [1 September 2020 19:51 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/15 "2020-09-01T19:51:11Z")

</div>

Good point. I forgot the context functions handle nested values along the path both ways.

---

<div class="post-metadata">

**Author:** ![Nodi.Rubrum](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/nodi.rubrum/32/107482_2.png) [@Nodi.Rubrum](https://discourse.nodered.org/u/Nodi.Rubrum)\
**Post date:** [2 September 2020 17:44 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/16 "2020-09-02T17:44:04Z")

</div>

Cool. Really did not intent to spark some much effort on this. I really can live without the periods. 🙂 But this just affirms this forum, when it gets a bone, often just never wants to let go!

When I use persistence... I often use a object structure, so I have one identifier, and a data structure behind it. Not sure where I developed such a habit, but it makes things easier, I think. It maybe just because when I need persistence, I happen to have a lot of data to handle, versus a variable here,or there type of thing.

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)\
**Post date:** [1 November 2020 17:44 UTC](https://discourse.nodered.org/t/no-periods-in-context-variable-names/32269/17 "2020-11-01T17:44:07Z")

</div>

Closed on 1 November 2020 17:44 UTC

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