# Context variable that (partly) references other context variables dynamically

**URL:** <https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624>\
**Category:** General\
**Tags:** home-assistant\
**Created:** [17 April 2025 14:20 UTC](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624 "2025-04-17T14:20:59Z")\
**Posts on this page:** 11\
**Page:** 2

<div class="post-metadata">

**Author:** ![mikefila](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mikefila/32/95223_2.png) [@mikefila](https://discourse.nodered.org/u/mikefila)\
**Post date:** [18 April 2025 08:48 UTC](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624/21 "2025-04-18T08:48:08Z")

</div>

In your example, you are setting a home assistant global to a value. I wanted to point out that doesn't work.

---

<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:** [18 April 2025 10:40 UTC](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624/22 "2025-04-18T10:40:50Z")

</div>

> [@mikefila](#):
>
> In your example, you are setting a home assistant global to a value

Not really. I don't have HA - it is simulating what HA might do to demonstrate how references work. The fact HA is mentioned is really of no relevance other than the OP uses HA and wants to reference a value that is set by HA.

> [@mikefila](#):
>
> I wanted to point out that doesn't work

And as I stated, I did that for demonstration purposes to simulate what HA does. The OP is aware of this based on their demo flow (they did not do direct setting of context values)

---

<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:** [18 April 2025 11:29 UTC](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624/23 "2025-04-18T11:29:00Z")

</div>

> [@Context Watcher](https://discourse.nodered.org/t/context-watcher/96637):
>
> I just posted a flow to the library that permits a user to watch memory based context variables and get an event with what changed. Might be of use to some folk. [chrome\_RU0ciSH6f3]

---

<div class="post-metadata">

**Author:** ![mikefila](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mikefila/32/95223_2.png) [@mikefila](https://discourse.nodered.org/u/mikefila)\
**Post date:** [18 April 2025 16:42 UTC](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624/24 "2025-04-18T16:42:41Z")

</div>

You are right the OP did not ask to set a global. While they might not want to set the value of a global now, they may want to in the future. The example you posted is misleading.

Your example, you are changing a copy of HA's state machine to forward the value to a flow variable. Problem is, your flow works, in the sense will update the flow variable with the value you set to the global.

However the global was not changed and moreover the actual entity the global represents has a different value then what was set to the flow 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:** [18 April 2025 21:39 UTC](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624/25 "2025-04-18T21:39:35Z")

</div>

> [@mikefila](#):
>
> The example you posted is misleading

The example I posted is a simulation since I don't have HA.

even if I did have HA, I would not have the same entities and I'd still have to simulate what HA does to demonstrate how references work.

I'm failing to see how that is unclear.

> [@mikefila](#):
>
> Your example, you are changing a copy of HA's state machine

No. I am setting a value of a global context variable that also has a reference set upto it's parent object in flow context. The fact it is named homeassistant is by the by in this demonstration.

> [@mikefila](#):
>
> However the global was not changed and moreover the actual entity the global represents has a different value then what was set to the flow variable.

Please remember I do not have HA and was simulating what HA does to global context. I merely pointed a flow variable at a global variable to demonstrate by reference changes. I never once inferred or stated this would affect the state of the HA entity. In fact I repeatedly said I was simulating of what HA might do (as in updating a value in global context).

---

<div class="post-metadata">

**Author:** ![mikefila](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/mikefila/32/95223_2.png) [@mikefila](https://discourse.nodered.org/u/mikefila)\
**Post date:** [19 April 2025 01:21 UTC](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624/26 "2025-04-19T01:21:51Z")

</div>

The globals are created and updated by HA, they are a copy of all entity states in home assistant.

Lets say I have a light in HA that is `off`. In NR I have a global for that light and it is also `off`. I can change that light global in NR to `on`.

Now anything in NR that uses that global sees that light as `on` when in reality it is off. The next time the entity updates in HA, the global returns to `off` since the actual state of the light has not changed.

Because this was a post about using NR with HA, knowing that you do not use HA, seeing the example you posted, I understand it is perfectly valid in NR, the clarification that it is not applicable to HA globals, I felt was relevant.

---

<div class="post-metadata">

**Author:** ![biscuit](https://avatars.discourse-cdn.com/v4/letter/b/f17d59/32.png) [@biscuit](https://discourse.nodered.org/u/biscuit)\
**Post date:** [19 April 2025 11:03 UTC](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624/27 "2025-04-19T11:03:27Z")

</div>

Interesting question.

Can a context variable partly reference another context variable? - Yes  
Does this work for the HomeAssistant WebSocket Global variable? - Yes _and_ No.

Part One:  
Since JavaScript under node.js does indeed keep objects on the heap and uses _copy by reference_ rather than _copy by value_, making a copy variable 'b' of an object variable 'a' just means that `a.whatever` is the same as `b.whatever`. This is something that caught me out when first using Node-RED, and I now always tick the 'deep copy' option in a change node to prevent one variable updating another unexpectedly.

This behaviour does indeed extend to context variables, which is where I first noticed it. Holding an object in `msg.payload` and copying (saving) to `flow.saved` (without the 'deep copy' option) means that subsequent changes to `msg.payload.whatever` also change `flow.saved.whatever`. A test with Change nodes shows that this "works" the other way around: copy `msg.payload` to context, change the context, and `msg.payload` changes also, and yes, copy a context object variable to another context variable and they are indeed linked by reference.

I can see that this occurs on a simple equivalence assignment, as in a = b, but then wondered if it also operates with assignment of sub-objects and super-objects. A quick test in JS in a function node confirms that it does.

```auto
let a =
{
    "top": {
        "middle_a": {
            "end_1": 1,
            "end_2": 2
        },
        "middle_b": {
            "end_3": 3,
            "end_4": 4
        }
    }
};

let b = a;
msg.a = a;
msg.b = b;
msg.a.top.middle_a.end_2 = 42;

let c = a.top.middle_a;
msg.c = c;
msg.c.end_2 = 50;

let d = {"mycopy": a, "other": "testing"};
msg.d = d;
msg.d.mycopy.top.middle_a.end_2 = 22;

return msg;

```

Returns as expected, with `a.top.middle_a.end_2` and `b.top.middle_a.end_2` and `c.end_2` and `d.mycopy.top.middle_a.end_2` are all `22`

Part Two:  
The Home Assistant WebSocket nodes work through a WebSocket server connection back to Home Assistant, and as far as I understand the workings, the entire HA state model is read or polled as required. This is in addition to the WebSocket listening to the HA event bus, so the WebSocket nodes respond to things like state changes by listening to events, and not by checking the state record. The state record copy to Global Context is optional, and I assume that the internal copy is used primarily (only) for _reference_ to such things as the services provided and for auto-complete of entity names in the node UI.

As such, the Context copy is for reference only, and it is unlikely that each _individual_ entity record is updated in the copy at each state-change event. My assumption is that the context record is overwritten in entirety (or as a block) as and when either an active node responds to an event, or on a regular basis if the heartbeat option is enabled.

So, after a bit of testing, I can get this to "work". But only so far.

If I copy the `homeassistant.homeAssistant.states` part of the Global Context variable, to a local flow variable, then my flow copy _is_ updated along with the HA Global (ie they both point to the same object in memory).

If I try to copy the `homeassistant.HomeAssistant.states["sensor.my_entity"]` part, then it does _not_ work.

 ![cross reference context variables is possible](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/b/d/bd21e0d557ad47de38c5a4c2b3f2328aedcfab93.png)

Since the copy is by reference, it could be argued that there is no extra overhead in keeping a duplication of the entire HA states in a flow context. However, getting at the actual state value still requires ["sensor.name"].state, and I am inclined to think that using a simple Events: states node to update a copy flow sub-object state value directly would be tidier.

 ![using an Event state node to update context](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/5/4563fc602bd89b38a04a2a51b2d08f6219d47319.png)

This still leaves the question as to why the reference copy does not work on the sub-object at the sensor level, and I wonder if the ["sensor.name"] referencing disrupts the usual assignment procedure. A quick check with JSONata using `$globalContext("homeassistant").ha1Pi52.states.'sensor.mb_load_power'` works up to the states field as before, but not for the individual sensor field value.

Well, that was slightly more interesting than doing my SuDuko this morning.

---

<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:** [19 April 2025 15:33 UTC](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624/28 "2025-04-19T15:33:29Z")

</div>

> [@biscuit](#):
>
> This behaviour does indeed extend to context variables

I will say this one more time. It extends to MEMORY BASED context variables. It DOES NOT extend to other types of context variables. Since those will all be, at some point, serialised and un-serialised. Serialising a JavaScript object will flatten a referenced object unless the context library has built in some mechanism to handle such a serialisation.

Even for file-based retained context variables, if you restart Node-RED, any reference will have been flattened.

---

<div class="post-metadata">

**Author:** ![biscuit](https://avatars.discourse-cdn.com/v4/letter/b/f17d59/32.png) [@biscuit](https://discourse.nodered.org/u/biscuit)\
**Post date:** [19 April 2025 15:50 UTC](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624/29 "2025-04-19T15:50:55Z")

</div>

> [@TotallyInformation](#):
>
> Even then, does that work when using get/set? I've never tried it.

I tried it. It works (at least for memory context, some of the time).

I'm sorry I posted. The Home Assistant forum is a lot more friendly and forgiving.

I won't bother you again.

---

<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:** [20 April 2025 10:00 UTC](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624/30 "2025-04-20T10:00:04Z")

</div>

Hey @biscuit dont be disheartened, we are good and helpful folk here but sometimes things can read / come across a bit unfriendly sometimes. I promise that is not our intention and knowing Julian, it was not his intention.

I appreciate you digging in and backing up what I was stating.

As you pointed out, some variables in HAs global "mirror" of its data are not possible to watch via a reference. This is the caveat I was referring to...

> [@Steve-Mcl](#):
>
> it is simulating what HA might do to

_Emphasis on "might"_

Your digging revealed HA (up to a point) leaves the original object but (by deduction) is replacing sub-property objects beyond `homeassistant.homeAssistant.states`. This was useful information. Thanks.

---

<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:** [19 July 2025 10:00 UTC](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624/31 "2025-07-19T10:00:49Z")

</div>

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

[Previous page](https://discourse.nodered.org/t/context-variable-that-partly-references-other-context-variables-dynamically/96624.md?page=1)
