# Retaining state information in a Dashboard 2 ui-template

**URL:** <https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007>\
**Category:** Dashboard\
**Tags:** dashboard-2\
**Created:** [28 February 2024 16:39 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007 "2024-02-28T16:39:05Z")\
**Posts on this page:** 20\
**Page:** 1

<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:** [28 February 2024 16:39 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/1 "2024-02-28T16:39:05Z")

</div>

I am retaining state information in a Dashboard 2 ui-template by saving it in a property (eg msg.\_mydata) in the message that gets sent back to the server. If the page is refreshed or a new browser window is opened on the page then it gets sent to the client instance of the template via the last message replay feature. Is that the recommended way to do this?  
It is working ok for me, apart from the fact that sometimes I do not want to send a message on to the next nodes in the flow. It would be good if there was a way of sending a message back to the server in a way that told the server not to send it on, or is this already possible?

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [28 February 2024 17:03 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/2 "2024-02-28T17:03:23Z")

</div>

For big table such thing can create duplcate of database. Or I don't follow it properly?

---

<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:** [28 February 2024 17:14 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/3 "2024-02-28T17:14:37Z")

</div>

The state is very simple, it consists of a value and an enable state. The flow sends the value in msg.payload, but the enable state is sent via a different message using msg.enabled. The 'latest msg replay feature' fails because the last message will either be a value or an enabled state, but not both. I don't want to have to join them before sending to the node as it is a dropin replacement for the standard ui- dropdown node. Ideally I would be able to put value and state into a msg property and send it back to the server, but tell the server not to send it on.

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [28 February 2024 17:31 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/4 "2024-02-28T17:31:25Z")

</div>

That's why I changed payload structure for compass to have both properties required. It's of course bad for user cos it takes some extra wiring and nodes in flow but keeps replay functionality correct. I'm not big fan of changing msg at frontend.

If widget's look depends on multiple properties it should actually be even clever to behave if one of them missing or don't behave at all if data is not complete. Incoming msg is not part of widget properties. It should be able to react on data and show it in the manner it is made for. Reply is only helper to not force users to create that replying system from scratch. That's all if msg remains as it was.

Yes I introduced a change of msg for dialog but that is kind of different. Get rid of msg is not as same as change it.

But who knows. This is only me and my doubts.

---

<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:** [28 February 2024 20:45 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/5 "2024-02-28T20:45:19Z")

</div>

> [@hotNipi](#):
>
> I changed payload structure for compass to have both properties required. It's of course bad for user

Exactly. That is why I want to avoid it.

> [@hotNipi](#):
>
> If widget's look depends on multiple properties it should actually be even clever to behave if one of them missing or don't behave at all if data is not complete.

It is not only look, it is functionality. It is not possible use a default value for missing data as it would then be possible for the same widget to be disabled in one browser and enabled in another viewing the same page.

> [@hotNipi](#):
>
> Replay is only helper to not force users to create that replying system from scratch.

Just because that was the original intention does not mean we cannot use it to the full extent of the possibility of the feature.

Ideally we should be able to do anything in a template widget that can be done in a core or contrib ui node. As far as I can see the main (only?) thing missing is that the template node does not have server side state (except via message replay). I don't know if it was a positive decision not to have server side state or whether it just was not considered. It is possible to get round the problem using message replay and 'hidden' properties, apart from the fact that it is not possible to tell the server not to send the message when its only purpose is to update the state on the server. An optional second parameter to send() to tell it not to send it on would (I think) get round the problem.

---

<div class="post-metadata">

**Author:** ![rko](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rko/32/45807_2.png) [@rko](https://discourse.nodered.org/u/rko)\
**Post date:** [29 February 2024 06:02 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/6 "2024-02-29T06:02:51Z")

</div>

@Colin, thanks to you I was finally able to narrow down a hiccup in one of my template nodes I am trying to migrate from D1. I've been wondering if this `replay feature` could be turned off, because I am reloading the data manually by sending multiple messages (traces) to a plotly graph. Or maybe I should send only one giant message and I could make use of the replay feature .. hmm.

EDIT: I think you are asking for the same thing in your previous reply? Sorry, my English.

EDIT EDIT: If only the `replay message` would be marked as such, I could skip it. But an option in the template to disable this completely would be the best solution I guess.

EDIT EDIT EDIT: [This](https://github.com/FlowFuse/node-red-dashboard/issues/428) seems related.

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [29 February 2024 06:20 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/7 "2024-02-29T06:20:24Z")

</div>

> [@rko](#):
>
> I've been wondering if this `replay feature` could be turned off

Can't be turned off but can be avoided.  
Get your data out of `msg.payload` and then get rid of the `payload`.  
And you guard it by checking if the payload property exist.

```auto
watch: {
        msg: function(){    
            if(this.msg.payload != undefined){           
                this.value = this.msg.payload                
                this.msg.payload = null
            }
        }
    },

```

---

<div class="post-metadata">

**Author:** ![rko](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/rko/32/45807_2.png) [@rko](https://discourse.nodered.org/u/rko)\
**Post date:** [29 February 2024 06:37 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/8 "2024-02-29T06:37:04Z")

</div>

Not sure I follow. It always sends an exact copy of the last message whether there is a payload or not.

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [29 February 2024 07:02 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/9 "2024-02-29T07:02:28Z")

</div>

It sends but you don't act on msg's where payload is missing.

---

<div class="post-metadata">

**Author:** ![BartButenaers](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/bartbutenaers/32/10476_2.png) [@BartButenaers](https://discourse.nodered.org/u/BartButenaers)\
**Post date:** [29 February 2024 07:07 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/10 "2024-02-29T07:07:03Z")

</div>

> [@hotNipi](#):
>
> > [@rko](#):
> >
> > I've been wondering if this `replay feature` could be turned off
> 
> Can't be turned off but can be avoided.

Hi @hotNipi,  
I kind of got lost in the data handling of D2. So the msg replay mechanism is still available in D2 you say? I had proposed at the start of the D2 developments (see [here](https://github.com/FlowFuse/node-red-dashboard/issues/61#issuecomment-1684530029)) to avoid doing that, because it gave a lot of headache for developers in D1. Thorsten did not use it anymore in Flexdash (for obvious reasons), so that is why I shared his experience in that issue. However due to free time constraints, I did not follow up this afterwards. So we do have to take the msg replay into account again while developing ui nodes?

If somebody thinks my feedback is off-topic, please don't hesitate to split my post into a new discussion!  
Bart

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [29 February 2024 07:09 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/11 "2024-02-29T07:09:00Z")

</div>

I saw request in backlog that it should be configurable. But for sure it exists for now.

---

<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:** [29 February 2024 07:14 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/12 "2024-02-29T07:14:10Z")

</div>

> [@hotNipi](#):
>
> Get your data out of `msg.payload` and then get rid of the `payload`

I believe that will only work if you send the message back to the server, otherwise how will the server know to change it in it's stored copy of the message? Which brings us back to being able to send a message to the server but flagging it for not being sent out.

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [29 February 2024 07:16 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/13 "2024-02-29T07:16:43Z")

</div>

I believe that `this.msg` is reference to same object you'll get back as replay. It works obviously. Doesn't it? For dialog it works why not for others?

EDIT: Wait, Ill check something and come back with it. Cos we are talking a bit different situations maybe...

With msg watcher:

```auto
watch: {
        msg: function(){    
            if(this.msg.payload != undefined){     

```

You get replay message and only way to get rid of it is to send msg with `payload = null`

With direct socket listening:

```auto
mounted() {            
            this.$socket.on('msg-input:' + this.id, function (msg) {                
                console.log("msg from socket:",msg)

```

You don't get any replay messages what so ever.  
Still you can listen replay by watching msg and do whatever symbiosis then

---

<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:** [29 February 2024 08:55 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/14 "2024-02-29T08:55:13Z")

</div>

OK, that is good to know, but it isn't actually the main point of the thread, which is how to maintain state for a ui-template over, for example, page refresh. The solution I have come up with, to use replay, with a 'hidden' property of the message, works fine, except that the only way I can get it back to the server is via this.send() which I don't always want to do as it sends a message out of the node which may not be desirable.

---

<div class="post-metadata">

**Author:** ![Buckskin](https://avatars.discourse-cdn.com/v4/letter/b/b9e5f3/32.png) [@Buckskin](https://discourse.nodered.org/u/Buckskin)\
**Post date:** [29 February 2024 17:19 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/15 "2024-02-29T17:19:51Z")

</div>

How about` HTML localStorage`. Saves data in the browser but is available after a page refresh

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [29 February 2024 19:01 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/16 "2024-02-29T19:01:29Z")

</div>

It would work but again - that kind of usage is like creating another instance of database.

Don't think about it as one node and one property. It's dashboard which can have a lot of things. There's no restrictions to store a chart data to local store but if you have a year amount of data for twenty charts ..

Also the state or part of the state if determined on incoming message is already old. At least couple of milliseconds. So it can't be real state of anything. The reason to rely on that data is getting smaller and smaller every second.  
Opening the dashboard next Thursday and showing that stored data makes untrustworthy results and nothing more.

So the reply can help, but shouldn't taken as must or an obstacle. Every situation is a bit unique so it should be easy to choose how it should behave.

---

<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:** [29 February 2024 21:39 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/17 "2024-02-29T21:39:46Z")

</div>

> [@Buckskin](#):
>
> How about` HTML localStorage`

That won't work for me, it has to be in the server. One of the properties is the disabled state. It is a dropdown select box that can be disabled by the flow to prevent operator input. If the node is disabled and then another user opens a browser window on the node it has to be in the disabled state. The core ui nodes presumably use server side state for such information. In fact the core dropdown node supports enable/disable so presumably it must have server side state to retain this.

---

<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 March 2024 14:40 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/18 "2024-03-01T14:40:50Z")

</div>

Having done some more work I think there is no solution to my problem, other than to add support nodes to the flow.  
The fundamental problem is that I need to build up the state of the widget based on a sequence of messages coming in. As I understand it there is no server side storage associated with the template other than the configuration and the last message sent. My proposed solution was to build up the state client side and include the state in messages sent by the node, such that it gets saved in the 'last message sent' and then if the browser is refreshed, or a new client connects, the state information is available. The problem is that that fails completely if there is no client connected.

So unless someone can offer a solution I have no option other than do something like adding a Join node in front of each widget and making sure that the messages have appropriate topics.

---

<div class="post-metadata">

**Author:** ![hotNipi](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/hotnipi/32/383_2.png) [@hotNipi](https://discourse.nodered.org/u/hotNipi)\
**Post date:** [1 March 2024 14:45 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/19 "2024-03-01T14:45:56Z")

</div>

You have reached to same conclusion I had. Hope that maybe at some point the storage api reaches to `ui_template` node somehow...

---

<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 March 2024 14:57 UTC](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007/20 "2024-03-01T14:57:44Z")

</div>

I think the template needs another section, which is run in the server. So effectively the template has an attached Function node which can save state and can communicate with the attached clients as appropriate.

If core and contrib widgets have the same restriction then that means that there may be no solution to [issue 622](https://github.com/FlowFuse/node-red-dashboard/issues/622) and I think the other nodes that have state, such as dropdown and text input, will also have the problem that enabling/disabling will destroy the current state.  
I don't know whether D1 had that problem or not....

**[Edit]** With D1 for the same tests as described for issue 622, the switch does not lose its state over enable/disable, though it does lose the saved topic. I deduce from that that D1 must have some state storage in the server, other than the last message sent. I also deduce that losing the topic is not a serious issue as apparently no-one has noticed it. I think that losing the switch state as D2 does is not good.

[Next page](https://discourse.nodered.org/t/retaining-state-information-in-a-dashboard-2-ui-template/86007.md?page=2)
