# VueJs - where to store my data

**URL:** <https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939>\
**Category:** Developing Nodes\
**Tags:** dashboard-2\
**Created:** [26 February 2024 20:14 UTC](https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939 "2024-02-26T20:14:06Z")\
**Posts on this page:** 11\
**Page:** 1

<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:** [26 February 2024 20:14 UTC](https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939/1 "2024-02-26T20:14:06Z")

</div>

Hi folks,

Whenever I have an hour free, I try to start migrating my old ui nodes to D2. But due to my lack of Vue knowledge, I find it rather difficult to get started. Seems that Vue is doing a lot of magic behind the scenes, but that makes it even more difficult for me to get a hold of it.

I have lost completely track about where all my data needs to be stored. I read [this](https://github.com/FlowFuse/node-red-dashboard/blob/main/docs/contributing/widgets/third-party.md#the-basics-of-vuejs) documentation, but it is still foggy in my head.

For example:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/4/c/4c2dbf46184a08f0100d11707b3a9253283be5c7.png)

1. The `{{ props.label }}` in my template is binded to my _ **props.props** _. So the props contain (immutable?) data arriving from the config screen of my ui node. Personally I find it rather confusing to have 2 nested props levels, especially since the upper props level seems nowhere to be used. I assume that is part of the Vue magic...

2. Then there is _ **props.state** _. I thought first that this is some volatile state of my widget, which gets lost (after a refresh?). But I seem to remember that I read somewhere that state on the server side is also used to store the dynamic settings arriving via input messages (which overrule the corresponding settings from my ui node's config screen)? But perhaps I am mistaken. So not sure whether I can store here some of my custom state, without it being overwritten by the dashboard?

3. Then there is the _ **data** _ section. Not sure for which data this is used.

4. There are also _ **Vuex datastores** _. Is that for persistent data, or is it the same as the above props in some way? Because it also seems to be used to store state...

5. In the above example the props.label is showed in the widget. While I understand that is useful for fixed texts, in my use case I need to be able to change the label afterwards. Does this mean I need to copy in js code my props.label content to somewhere else, and then somehow bind that intermediate variable to my widget? Or perhaps that needs to go into the _ **computed data** _ section?

6. Then there is the data being stored in the _ **input messages** _, and those messages are also being stored somewhere. Not sure anymore if there is a msg replay mechanism (e.g. at browser refresh) like in the old days?

7. It is also not clear to me how and when the data is transported between the server side and the client side. For example when I save data to the server-side datastore, what happens then? Or when a client connects, how it loads his data from my server. While some developers might not need this kind of information, it would help me to find a good mechanism to store and share my state in the SVG node...

I had hoped my [cheat sheet](https://github.com/FlowFuse/node-red-dashboard/issues/404#issuecomment-1847899338) would gain me some insights in how it is all glued together, but my sheet is lacking too much information to be of any help unfortunately ☹

I have similar issues with my migrated [heatmap](https://github.com/FlowFuse/node-red-dashboard/pull/577) node. It looses all his data when the browser window has refreshed. No idea how to solve that to be honest. Should have more time to read about Vue and experiment with it, but that is completely no option for me at the moment.

Thanks for illuminating me!!

Bart

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [26 February 2024 20:31 UTC](https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939/2 "2024-02-26T20:31:06Z")

</div>

Just to put a quick note to say that some of these are Vue things, some are my design decisions, some of it a little legacy that I need to clean out (props.state I dont think is used anymore, but need to double check)

I will give you a full descriptive answer to each of your points tomorrow!

---

<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:** [26 February 2024 22:28 UTC](https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939/3 "2024-02-26T22:28:34Z")

</div>

> [@joepavitt](#):
>
> I will give you a full descriptive answer to each of your points tomorrow!

I you need to prepare things for your webinar, please let this wait for a couple of days!!

For anybody interested in this topic. I have been looking this evening for some visual explanation of how it works, but I assume I am using the wrong keywords because couldn't find much. Which would be weird.

Did some quick drawing, and here is what I found so far:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/3/2/321e7d50ddfd34323600fcd8fab9c731f90b6d3d.png)

Noob level stuff, but need to start somewhere...

---

<div class="post-metadata">

**Author:** ![Paul-Reed](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/paul-reed/32/66906_2.png) [@Paul-Reed](https://discourse.nodered.org/u/Paul-Reed)\
**Post date:** [26 February 2024 23:03 UTC](https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939/4 "2024-02-26T23:03:36Z")

</div>

> [@BartButenaers](#):
>
> Noob level stuff,

Now you're damaging [my self esteem](https://discourse.nodered.org/t/dashboard-2-multi-state-switch/85168/37) 🤨

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [27 February 2024 11:43 UTC](https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939/5 "2024-02-27T11:43:04Z")

</div>

### 1. `props`

> 1. The `{{ props.label }}` in my template is binded to my _ **props.props** _. So the props contain (immutable?) data arriving from the config screen of my ui node. Personally I find it rather confusing to have 2 nested props levels, especially since the upper props level seems nowhere to be used. I assume that is part of the Vue magic...

So, this is perhaps bad attribute naming on my part, but the breakdown is two-fold:

```js
props: {
    ....
}

```

On the component definition is a [VueJS Options API](https://vuejs.org/api/options-state.html#options-state). `props` is a schema to tell anything else in our Vue app what inputs/properties this component needs in order to render. So, for example `<my-component prop1="" prop2="" />`

Our widget specification is driven by three properties: `id`, `props` and `state`.

`id`: The ID given to the node/widget from Node-RED  
`props`: The object sent by `ui-base` as part of the `ui-config`, which bundles together the appropriate values from the Node-RED configuration for that node, perhaps `config` would have been a better choice of variable names, rather than the double `props`, this is something I'm definitely open to changing for easier readability.  
`state`: This is meant to be providing details on anything overridden at runtime, but I haven't implemented this consistently, entirely my fault.

### 2. `props.state`

> 1. Then there is _ **props.state** _. I thought first that this is some volatile state of my widget, which gets lost (after a refresh?). But I seem to remember that I read somewhere that state on the server side is also used to store the dynamic settings arriving via input messages (which overrule the corresponding settings from my ui node's config screen)? But perhaps I am mistaken. So not sure whether I can store here some of my custom state, without it being overwritten by the dashboard?

My original plan for `props.state` was to store _dynamic_ content in here, i.e. visibility, disabled state, etc. but the lines between `props` and `state` were not clear, as often you can override the `props` at runtime, e.g. `options` on a `ui-dropdown`. The difficulty then came (which I can see you're facing in 5 is that I was duplicating effort client-side of having to constantly check both `props` _and_ `state`, and it's messy.

As a result, it's become a bit of a mish-mash of values that I really need to clean up and provide consistency on, but with all the new requests, bugs, etc. coming in, and now only working on Dashboard 2 days a week at most, spending a few days just doing technical debt, and ensuring cleaner documentation hasn't been possible.

Server-side, my architecture is a little cleaner, where I also use a store-based architecture, with `data` matching the behaviour of the client, i.e. storing message history, and the `statestore` (server-side) storing anything that is overridden from the base configuration, so Node-RED maintains the configuration defined at deploy-time, and then `statestore` keeps track of anything that has since changed. The two stores are then merged

### 3. data () { ... }

> 1. Then there is the _ **data** _ section. Not sure for which data this is used.

This is a part of the [VueJS Options API](https://vuejs.org/api/options-state.html#data) to define a Vue Component. `data ()` is entirely scoped locally to the Vue component, and defines variables that are used component-wide, i.e. rendered part of the HTML and/or used across JavaScript methods defined on the component too.

### 4. VueX Stores

> 1. There are also _ **Vuex datastores** _. Is that for persistent data, or is it the same as the above props in some way? Because it also seems to be used to store state...

[vuex](https://vuex.vuejs.org/) is used to persist data across the application in a centralised location, any component can read/write into the stores we have. Within Dashboard 2.0, I have the following stores:

- `data`: this stores any of the latest or historical messages for each widget/node
- `ui`: this stores the `ui-config` for the whole Dashboard as sent by Node-RED, including th full list of `pages`, `groups`, `themes` and `widgets`.
- `setup`: This is shoe-horned a little, but fundamentally stores the _setup_ object sent on first load, which in core provides the SocketIO configuration, generated server-side. It is also possible to extend this with the [Third Party Plugins](https://dashboard.flowfuse.com/contributing/plugins/) (and is what we use for the [Multi-User Dashboards](https://flowfuse.com/blog/2024/01/dashboard-2-multi-user/))

### 5. Dynamic Properties

> 1. In the above example the props.label is showed in the widget. While I understand that is useful for fixed texts, in my use case I need to be able to change the label afterwards. Does this mean I need to copy in js code my props.label content to somewhere else, and then somehow bind that intermediate variable to my widget? Or perhaps that needs to go into the _ **computed data** _ section?

So, the "cleanest" (I use this phrase in the loosest of terms) example I have for this is `ui-dropdown`. When a message is received with `.options` inside, server-side we have a `beforeSend()` handler, which is before it's sent to the client. This stores, in our server-side `statestore` any `msg.options` that are found.

Client-side, we then also check for `.options` when a new message is received in the custom `onInput` function, and store that locally on our component's `this.items`.

On refresh, our `ui-base`, when building the `ui-config` merges the configuration from Node-RED, which would still have the original `options` and the `statestore` into the widget configuration, so the latest `.options` would be provided to the client-side where they would be loaded and shown.

### 6. OnLoad

1. Then there is the data being stored in the _ **input messages** _, and those messages are also being stored somewhere. Not sure anymore if there is a msg replay mechanism (e.g. at browser refresh) like in the old days?

Each core widget can provide an `onLoad` function. When our client first loads a widget, the server-side will pass an `on-load` event via SocketIO with the latest `msg` it's aware of. So, if you want to load the latest state, provide a listener for `onLoad` client-side (for third party widgets - docs are [here](https://dashboard.flowfuse.com/contributing/widgets/third-party.html#loading-state)) which accepts that `msg` and does whatever you need to do with it on the client.

### 7. Data Transfer

> 1. It is also not clear to me how and when the data is transported between the server side and the client side. For example when I save data to the server-side datastore, what happens then?

Data being stored to the `statestore` just does exactly that, nothing is communicated to the client unless you explicitly request it to be. Our [Events Architecture](https://dashboard.flowfuse.com/contributing/guides/events.html) diagram does cover the foundatinal event structure between Client (in blue) and Node-RED (in red).

> Or when a client connects, how it loads his data from my server. While some developers might not need this kind of information, it would help me to find a good mechanism to store and share my state in the SVG node...

In this particular example, you see in the diagram linked above that we fire a `widget-load` event for each widget on the screen. The server-side nodes then send a `widget-load` event _back_ to the client with the latest `msg` stored in the server-side `datastore`

---

<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:** [27 February 2024 22:30 UTC](https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939/6 "2024-02-27T22:30:18Z")

</div>

Hi @joepavitt,  
Thanks for taking the time for giving so much feedback in depth!  
And all respect that things can grow out of hand when you have to develop something big like this from scratch in very short amount of time.

I am going to try to find some time in the next evenings to digest this info, and hopefully I can map all of it on my cheat sheet. The amount of missing arrows visualize the gaps in my knowledge 😉

Good luck with your webinar!!

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [28 February 2024 06:35 UTC](https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939/7 "2024-02-28T06:35:11Z")

</div>

I will also make sure i have some explicit examples added into the docs for your use case around data loading.

Fundamentally there are two options:

1. Utilise the in-built mechanisms if you only need the last message received, or if you want all messages received and stored.
2. Build your own with our datastores, that stores your own custom format - suspect you want this, and so I will document an example.

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [5 March 2024 14:10 UTC](https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939/8 "2024-03-05T14:10:47Z")

</div>

Issue to track doc changes: [Docs: Add better/updated documentation of the events hierarchy of Dashboard 2.0 · Issue #646 · FlowFuse/node-red-dashboard · GitHub](https://github.com/FlowFuse/node-red-dashboard/issues/646)

---

<div class="post-metadata">

**Author:** ![joepavitt](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/joepavitt/32/59722_2.png) [@joepavitt](https://discourse.nodered.org/u/joepavitt)\
**Post date:** [6 March 2024 19:04 UTC](https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939/9 "2024-03-06T19:04:21Z")

</div>

PR opened with improved diagrams and documentation: [Docs: Update Events & State Store Architecture Docs & Diagrams by joepavitt · Pull Request #647 · FlowFuse/node-red-dashboard · GitHub](https://github.com/FlowFuse/node-red-dashboard/pull/647)

---

<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:** [7 March 2024 19:54 UTC](https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939/10 "2024-03-07T19:54:15Z")

</div>

Hi @joepavitt,

> [@joepavitt](#):
>
> PR opened with improved diagrams and documentation: [Docs: Update Events & State Store Architecture Docs & Diagrams by joepavitt · Pull Request #647 · FlowFuse/node-red-dashboard · GitHub](https://github.com/FlowFuse/node-red-dashboard/pull/647)

I read through the readme files in your pull request, and that is much more clear. Thanks for all your efforts!! Really appreciated...

I am going to print your 3 separate diagrams on a large piece of paper, and put them beside me when I develop/migrate my ui nodes. I am pretty sure it will solve a lot of my headaches. When something is not clear, I will get back to you.

> [@joepavitt](#):
>
> `props`: The object sent by `ui-base` as part of the `ui-config`, which bundles together the appropriate values from the Node-RED configuration for that node, perhaps `config` would have been a better choice of variable names, rather than the double `props`, this is something I'm definitely open to changing for easier readability.

Personally I would find that much more readable. Because it is the config from the node's config screen in Node-RED, which arrives via ui-config in the dashboard. So if it would arrive at the end of the chain in props.config, that would make more sense to me.

> [@joepavitt](#):
>
> [vuex](https://vuex.vuejs.org/) is used to persist data across the application in a centralised location, any component can read/write into the stores we hav

Do I understand this correctly: if you need the data only inside your component (i.e. ui node) then you can put it in the `data`. And if you need the data across components, then you need to put it into a store? If correct, it might be useful for beginner developers to put that in the documentation. I didn't find it at first sight, but perhaps it is already there...

Although it is quite a lot to digest after a hard day of work (in other technologies), but you have provided all the bits and pieces that I needed. Now it is up to me and the other ui node developers to start puzzling. But gradually the fogs starts clearing in my mind...

Thanks again!!!!!!

---

<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:** [6 May 2024 19:54 UTC](https://discourse.nodered.org/t/vuejs-where-to-store-my-data/85939/11 "2024-05-06T19:54:32Z")

</div>

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