I can see from the docs Building Third Party Widgets how I can send a message without updating the data store and how to send a message and update the data store at the same time. How can I modify the store without sending a message? Ideally I don't want to update the entire store, just change one property therein.
Alternatively can I send an event with some data back to the server and handle the data store update myself?
Curious to know the use case here... all communication between client and NR is done via Sockets and utilising the msg
structure
You could introduce a custom event, and then have your server-side handler do whatever it needs to do.
I have adopted a slightly different data flow. In my server js file, as each message comes in I don't save the incoming message, as received, in the store, instead I build up the complete state in the data store as a set of properties. Then I just send any modified properties to the widget.
When a widget connects it gets sent the complete data store which allows it to initialise itself. Thereafter it expects just modified properties in the incoming messages which it uses to update its copy of the data.
So in the initialisation section of the js file I have
// initialise data store
base.stores.data.save(base, node, {/* default values if any */})
And in onInput
, showing the code for just one property
// pick up existing stored data
let storedData = base.stores.data.get(node.id)
...
// pick up msg.formattedValue if present and is a string
if (typeof msg.formattedValue === "string") {
storedData.formattedValue = msg.formattedValue
}
...
// store the latest values in our Node-RED datastore
base.stores.data.save(base, node, storedData)
// send the message containing just modified properties to attached clients
send(msg)
In the vue file I have exactly the same code processing the message in this.$socket.on('widget-load:'...)
and in this.$socket.on('msg-input:'...
. This looks for the expected properties in the message and updates the client side copy accordingly. Then the vue bindings update the DOM automatically. As you can see it is extremely easy and works perfectly, so far at least. Hopefully I have not misunderstood something vital in all this.
The final part of the puzzle is how to handle it if a property changes state in the client, a user clicks a switch for example. I need to update that property in the server data store, but if I use the method of sending a message then the message would have to contain the complete data structure which would be horribly wasteful. So I just need a way of telling the server to update a property in the data store to a new value.
Do you see any problems with that approach @joepavitt?
Haven't had a chance to do the reading of this justice, will hopefully get to it today
Ok, sorry, I didn't mean to hassle you.
Can D2 cached data be retained across Node-RED restarts?
It cannot - we bind data against the nodes themselves. Although, I opened New Nodes: In/Out User-Specific Context Store · Issue #1009 · FlowFuse/node-red-dashboard · GitHub today, which if setup with persistent storage, then yes, would persist beyond a restart
Presumably a third party node would be able to access the node red context in it's server side .js file, if it had a particular requirement that needed it.
I believe so. @Steve-Mcl I can't see any docs on it, but I suspect this is possible?
Yes, it is possible though you should be very clear about what and why in your docs/help info.
For example, I would not be happy if a node was using was accessing (and potentially overwriting) my flow or global context data.
For a quick how to see the additions commit on cron-plus
: add context as persistent store target · Steve-Mcl/node-red-contrib-cron-plus@77cf52c · GitHub
It uses own node context only and presents the user with a choice of available context stores
Some of the UIBUILDER nodes do this as well, notably the uibuilder cache node.
It can be useful to use a store that other things can also manage - but as you say, there are plenty of risks.
This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.