Access to context Stores in JSONata expressions


#1

I have found that $globalContext() function in JSONata functions only access stores in memory and does not access stores on disk. I assume $flowContext() will have some issue.

Inserting a Change node where I set a copy (temporary) of the global variable in memory (same name) is a temporary fix but is a issue when I change variables (more work to transfer changes from memory copy to disk.
I see in functions the get function now has another parameter to specify which store the variable is in but found no information on the JSONata function (it is NR specific).
Thanks


#2

PS, just updated Node-Red and related programs only a week back. So using NR 0.19.5 on latest Raspbian. Access through W10 via latest Chrome.


#3

Can you post a simple flow showing the problem?


#4

Hi @IanH

you are right - the JSONata functions dont let you specify the context store to get from. I'll get that added for 0.20.


#5

I take that back - I was looking in the wrong place.

The flowContext and globalContext functions in a JSONata expression can take two arguments. The first is the name of the context value, the second (optional) argument is the name of the store to get it from.

What's missing is an update to the docs to reflect that. Will get that updated in 0.20 - but functionally, it's all there in 0.19


#6

I was going to comment on that because I know I've used that on 0.19.5 :smile:


#7

Thanks Nick, would be nice to see some documentation on Node Red specific JSONata functions as they are not covered on JSONata.org. will give it a go tonight.
I assume I can add a icon property to the context store definitions in the settings.json file so they have a different co text stores have a different icon in dialogue boxes. (I saw a icon property on something else in that file so hoped it could be applied to co text stores definition).
Other wise thanks for context stores on disk, made my life easier.


#8

OK, got this working with a Change Node (but that was just for debug), but refuses to work on a switch node (in my case JSONata is in the property field). The JSONata evaluates to an integer.
The attached flow has a Change Node and Switch node fed by the same message.

The Change node {name: "Read file:Zones elements"} produces a valid output JSON as follows

{"_msgid":"96befb43.0300d8","topic":"","payload":{"ontime":"16:54","total":2,"Today":17964,"DayLastWatered":17960,"Period":2},"thisZone":0,"Today":17964}

Note the msg.payload.total evaluates to 2, this is what I expect in the switch node property.

The Switch node {name:"Watering Due"} reports an error as follow

Error: Invalid JSONata expression: Cannot read property 'Zone' of undefined

This is a snippet of the flow, just needs the node {name:"All Zones Done"} fed with msg.thisZone=0 and msg.Today=17964.

[{"id":"721d778f.e33648","type":"change","z":"ea51febe.392e5","name":"Next thisZone","rules":[{"t":"set","p":"thisZone","pt":"msg","to":"msg.thisZone+1","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":640,"y":400,"wires":[["543b1a39.2a9ff4","eeb1e93b.25dca8"]]},{"id":"543b1a39.2a9ff4","type":"switch","z":"ea51febe.392e5","name":"All Zones Done","property":"thisZone","propertyType":"msg","rules":[{"t":"gte","v":"#:(file)::Zones.ZonesQty","vt":"global"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":140,"y":400,"wires":[["7a418753.e9a628"],["a6c43cb6.64ee4","2a2e0f5c.ceea1"]],"outputLabels":["finished","Check next Zone"]},{"id":"a6c43cb6.64ee4","type":"switch","z":"ea51febe.392e5","name":"Watering Due","property":"msg.Today - (\t   $globalContext(\t       \"Zones.Zone[\" & $string(msg.thisZone) & \"].DayLastWatered\",\t       \"file\"\t   )     \t   + $globalContext(\t       \"Zones.Zone[\" & $string(msg.thisZone) & \"].Fixed.Period\" ,\t       \"file\"   \t   ) \t)","propertyType":"jsonata","rules":[{"t":"gte","v":"0","vt":"num"},{"t":"else"}],"checkall":"true","repair":false,"outputs":2,"x":380,"y":400,"wires":[["f452e453.78e958","721d778f.e33648"],["721d778f.e33648"]],"outputLabels":["Water","Do Not water"]},{"id":"f452e453.78e958","type":"debug","z":"ea51febe.392e5","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":630,"y":480,"wires":[]},{"id":"7a418753.e9a628","type":"debug","z":"ea51febe.392e5","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":350,"y":360,"wires":[]},{"id":"eeb1e93b.25dca8","type":"debug","z":"ea51febe.392e5","name":"","active":false,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":860,"y":400,"wires":[]},{"id":"2a2e0f5c.ceea1","type":"change","z":"ea51febe.392e5","name":"Read file:Zones elements","rules":[{"t":"set","p":"payload.total","pt":"msg","to":"msg.Today - (\t   $globalContext(\t       \"Zones.Zone[\" & $string(msg.thisZone) & \"].DayLastWatered\",\t       \"file\"\t   )     \t   + $globalContext(\t       \"Zones.Zone[\" & $string(msg.thisZone) & \"].Fixed.Period\" ,\t       \"file\"   \t   ) \t)","tot":"jsonata"},{"t":"set","p":"payload.Today","pt":"msg","to":"msg.Today","tot":"jsonata"},{"t":"set","p":"payload.DayLastWatered","pt":"msg","to":"$globalContext(\t   \"Zones.Zone[\" & $string(msg.thisZone) & \"].DayLastWatered\",\t   \"file\"\t\t\t) ","tot":"jsonata"},{"t":"set","p":"payload.Period","pt":"msg","to":"$globalContext(\t   \"Zones.Zone[\" & $string(msg.thisZone) & \"].Fixed.Period\",\t   \"file\"\t\t) ","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":390,"y":480,"wires":[["7909d6b1.5ef2b8"]]},{"id":"7909d6b1.5ef2b8","type":"debug","z":"ea51febe.392e5","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":710,"y":520,"wires":[]}]

The file:Zones Object contains

{"PumpMaxDel":50,"DailyStart":"16:54","ZonesQty":8,"Zone":[{"Number":0,"Name":"Spare","Description":"Spare outlet on Vege Patch Solinoids for solinoid switched hose","FlowRate":20,"Enable":"Off ","Fixed":{"Duration":60,"Period":2},"Evap":{"Defined ":false},"DayLastWatered":17960},{"Number":1,"Name":"Bed 1","Description":"Inside Vege bed nearest to Skillion Shed","FlowRate":6,"Enable":"Fixed","Fixed":{"Duration":60,"Period":2},"Evap":{"Defined ":false},"DayLastWatered":17962},{"Number":2,"Name":"Bed 2","Description":"Inside Vege bed second nearest to Skillion Shed","FlowRate":3.55,"Enable":"Fixed","Fixed":{"Duration":60,"Period":2},"Evap":{"Defined ":false},"DayLastWatered":17961},{"Number":3,"Name":"Bed 3","Description":"Inside central Vege bed ","FlowRate":6,"Enable":"Fixed","Fixed":{"Duration":60,"Period":2},"Evap":{"Defined ":false},"DayLastWatered":17960},{"Number":4,"Name":"Bed 4","Description":"Inside Vege bed second nearest to Creek","FlowRate":6,"Enable":"Fixed","Fixed":{"Duration":60,"Period":2},"Evap":{"Defined ":false},"DayLastWatered":17964},{"Number":5,"Name":"Bed 5","Description":"Inside Vege bed  nearest to Creek","FlowRate":6,"Enable":"Fixed","Fixed":{"Duration":60,"Period":2},"Evap":{"Defined ":false},"DayLastWatered":17963},{"Number":6,"Name":"East Bed","Description":"Outside Vege bed nearest to Skillion","FlowRate":10,"Enable":"Fixed","Fixed":{"Duration":60,"Period":2},"Evap":{"Defined ":false},"DayLastWatered":17962},{"Number":7,"Name":"West Bed","Description":"Outside Vege bed nearest to Creek","FlowRate":10,"Enable":"Fixed","Fixed":{"Duration":60,"Period":2},"Evap":{"Defined ":false},"DayLastWatered":17961}]}

Changing global variable inside the function node
#9

Nick,
Thanks for your response, which works on a Change Node but there is still a problem using the globalContext functions in a switch node when accessing a "file" context store. Exactly the same JSONata code works in Change Node and not in a Switch node, at least when used in the property field (both Nodes have the same msg feeding them).
An interesting twist (was my temporary workaround) is it works (stops reporting error and functions correctly for me) was if I copied the context store object from "file" to "memory" context store, then the switch node works, even though it still has the "file" parameter in the globalContext function. It is like it is ignoring that context store parameter and only using "memory" context store for JSONata in switch node Property.
More detail in my post from 6 days ago, just chasing this as I suspect it is a bug, and you may have not seen latest post.
Thanks.


#10

Your code snippets can not be imported, they generate Error: Input not a JSON Array

If you can reproduce this, create a small flow showing the issue so the problem can be tracked down.