Questions about creating D2 ui nodes and the node red data stores

I am creating a D2 ui node and having some problems with the server side data store.
Following the docs and the example ui node I have, in onInput() in the node's js file

                // store the latest value in our Node-RED datastore
                base.stores.data.save(base, node, msg)
                // send it to any connected nodes in Node-RED
                send(msg)

Then in the .vue file I have

    mounted () {
        this.$socket.on('widget-load:' + this.id, (msg) => {
        ...

So when the browser connects or is refreshed it first receives the new config properties, then it receives a message containing the current data store. This works OK.

The problem I have is that if I edit the node and deploy then connected browsers receive the new config properties, but are also sent the message with the old data store contents, which may not be compatible with the new config.

I had expected that the server side data store would be cleared when a node is deployed, which appears not to be the case. So question 1. - Is this a bug or is there a reason for it?

The solution I came up with was to manually clear out the datastore when the node is recreated, so I added code to that in the .js file so that I now have

        RED.nodes.createNode(this, config)
        const node = this
        // which group are we rendering this widget
        const group = RED.nodes.getNode(config.group)
        const base = group.getBase()

        // clear the server side data store, this ensures it is cleared if the node is deployed
        console.log(`clearing server data store`)
        base.stores.data.save(base, node.id, {})
        ...

and I can see that is running as the console.log message appears in the log, but still the browser receives the old message with the invalid data. So question 2 is what am I doing wrong?

I didn't want to clear the data store at this point because in any of the cases I could think of, the msg history should still be applicable to a node, although now you've got me thinking about it, and I'm not sure. If we do a "full deploy" - that would clear msg history for all UI nodes, and that feels a little too easy to do by accident?

Do you know why my code does not clear it on deploy?

And the answer as to why
base.stores.data.save(base, node.id, {})
does not clear down the data store to an empty message is that is should apparently be
base.stores.data.save(base, node, {})
So there appears to be a typo in the docs.

This API seems rather confusing as it appears that to get the current contents of the store one uses
base.stores.data.get(node.id)
but to set it one uses
base.stores.data.save(base, node, <data>)

1 Like

BTW Colin,
You also have the option to clear the server datastore using
base.stores.data.clear(node.id);
After which the "get" from the datastore returns undefined
(which is easier to determine as "empty" than a property-less object, though currently it will not be sent on 'widget-load')

Thanks, in fact either will do me, all I need to do is make sure that, after deploy, the data store does not contain information relating to the previous configuration, which may not be compatible with the new configuration.

Is the store API documented anywhere, or have you determined this from the code?

I took it from code in one of the examples

Sorry for the discrepancy Colin - I'll update the docs..

EDIT: Actually, the docs do list this already as it is, which docs were you seeing?

Docs: State Management | Node-RED Dashboard 2.0

Yeah, there are reasons, but I appreciate that's a confusion.

The reason is that save needs to check user permissions and any constraints set on a given node type (which relies on the msg._client value, so needs the full object).

The get is available to all, and so only needs the node's id

1 Like

The creating third party widgets guide Building Third Party Widgets | Node-RED Dashboard 2.0 says:

Then, whenever you want to store data in the datastore, you can do so with:

base.stores.data.save(base, node.id, msg)

I had not even seen the State Management guide. I think a link to there from the creating widgets guide would be good.

On the API, it seems odd to have to pass base across when it is referenced by base.stores.data.save.

Yeah, I regret that, but the challenge now is backward compatibility - removing it would cause a lot of headaches.

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