Global context variables do not display in the Context Sidebar

What if he tries upgrading to node-red 0.19.4?

Might have kind of point in here. I missed 0.19.3 in both my systems.

I just upgraded to 0.19.4... It still isn't showing any Global Context variable information in the Context Sidebar.

:persevere:

However, I added the contextStorage... localfilesystem syntax to the settings.js and that's working great.

This is not how I configured in my system. I added the context storage at the very end.

logging: {
        // Only console logging is currently supported
        console: {
            // Level of logging to be recorded. Options are:
            // fatal - only those errors which make the application unusable should be recorded
            // error - record errors which are deemed fatal for a particular request + fatal errors
            // warn - record problems which are non fatal + errors + fatal errors
            // info - record information about the general running of the application + warn + error + fatal errors
            // debug - record information which is more verbose than info + info + warn + error + fatal errors
            // trace - record very detailed logging + debug + info + warn + error + fatal errors
            // off - turn off all logging (doesn't affect metrics or audit)
            level: "info",
            // Whether or not to include metric events in the log output
            metrics: false,
            // Whether or not to include audit events in the log output
            audit: false
        }
    },
    editorTheme: {
        projects: {
            enabled: true
        }
    },
    contextStorage: {
        default: {
            module: "localfilesystem"
        },
        memoryOnly: {
            module: "memory"
        }
     }
}

So you see your global context stored in filesystem in folder C:\Users\YourUserName\ .node-red\context\global\global.json but still nothing in right side panel? is this correct?

Andrei,
How are you switching between the default persistence and the memory type? Do you specify that somewhere else in the configuration or does it only load the "default" and you change that in the file here?

All about presistable context storage
https://nodered.org/docs/user-guide/context

yes, it's in the file. Also There IS Flow Context Data. on the Flow tab. it works when I switch the flow tabs.

I do like explained in the middle of this post...

So this is certainly something for @knolleary to figure out. Needs deep knowledge of whole thing here. Very strange indeed.

Please don't let me stop y'all trying to figure it out whilst I'm busy with other things.

We tried. We failed. Sorry :no_mouth:

:pleading_face:

Andrei,
Thanks, I had not connected the dots... I had wondered how you could select type of storage since you probably only want a select few of variables to be persistent. Otherwise you need to do a bunch of clean-up initializing values at re-starts. That view of the change node configuration explained a bunch. And the documentation has been updated to explain it as well.

Thanks,

1 Like

And it works very well too - based on what Andrei told me in that previous thread i have been using it for about 4 or 5 days now and no problems. One surprise i had - i thought a deploy would clear out the memory variables - it does not - you neeed a Systemctl restart nodered for that to happen

Craig

I tried yet another thing this morning... I installed "node-red-contrib-contextbrowser" so I would have this function in another capacity... It does not work.

It does show information however. It shows
GLOBAL:
|Info|
|Name|-|
|Type|-|
|Id|Open|
|Timestamp|09/20/18, 09:09:13|

FLOW:
Info
Name - Flow 1
Type- tab
Id d0ab1f89.619cf
Timestamp 09/20/18, 09:12:58

But nothing useful.

Yes, Injected nodes, refreshed, re-started Node-RED, Refreshed Context browser etc..

Nick,
I have a question for you.
I copied this flow from the "flows" title:

"Function that dumps all context.global vars to debug window"

[{"id":"26917602.d96e8a","type":"inject","name":"trigger","topic":"","payload":"","payloadType":"string","repeat":"","crontab":"","once":false,"x":274,"y":163,"z":"1115f4b3.eeea0b","wires":[["3d0110db.c2fef"]]},{"id":"3d0110db.c2fef","type":"function","name":"dump: context.global ","func":"// dumps all vars in context.global \nvar objs = \"context.global: \";\n\nfor(var index in context.global) { \n   if(typeof context.global[index] == \"object\"){\n     \tobjs +=  \" \" + showKeys(index,context.global[index]);\n\t} else {\n\t   objs += \" \"+ index+\":\"+context.global[index]+\" , \"; \n\t}\n}\n\nfunction showKeys(parent,keys){\n   \tvar tkeys=\"\";\n   \tfor(var subIndex in keys) { \n\t\tif(typeof context.global[parent][subIndex] == \"object\"){\t\t\n\t\t\ttkeys += \" \"+ showKeysKeys(subIndex,context.global[parent][subIndex],parent);\n\t\t} else {\n\t\t\ttkeys += \" \"+ parent+\".\"+subIndex+\": \"+context.global[parent][subIndex]+\", \";\t\n\t\t}\n\t}\n\treturn tkeys;\n}\n\nfunction showKeysKeys(parent,keys,pp){\n   \tvar tkeys =\"\";\n   \tfor(var subIndex in keys) { \n\t\t\ttkeys += \" \"+pp+\".\"+parent+\".\"+subIndex+\": \"+context.global[pp][parent][subIndex]+\", \";\t\n\t}\n\treturn tkeys;\n}\n\nmsg.payload = objs;\nreturn msg;","outputs":1,"x":516,"y":162,"z":"1115f4b3.eeea0b","wires":[["870a5c65.78f5a"]]},{"id":"870a5c65.78f5a","type":"debug","name":"show","active":true,"console":"false","complete":"payload","x":733,"y":162,"z":"1115f4b3.eeea0b","wires":[]},{"id":"d314beef.2ceb4","type":"inject","name":"delete var","topic":"all","payload":"","payloadType":"string","repeat":"","crontab":"","once":false,"x":270,"y":198,"z":"1115f4b3.eeea0b","wires":[["b6240402.49dbf8"]]},{"id":"4fbef425.b0410c","type":"function","name":"Set vars example","func":"context.global.myvar = \"foo\";\ncontext.global.myarry = [\"foo\",\"/\",\"bar\"];\ncontext.global.debug = context.global.debug || {state:0, statePrevious: {pa:1,pb:2,pc:3}, darry: [0,1,2,3] };","outputs":1,"x":516,"y":234,"z":"1115f4b3.eeea0b","wires":[["870a5c65.78f5a"]]},{"id":"71b65ee1.8e49a","type":"inject","name":"trigger","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":274,"y":235,"z":"1115f4b3.eeea0b","wires":[["4fbef425.b0410c"]]},{"id":"b6240402.49dbf8","type":"function","name":"delete vars from global.context","func":"// Delete vars\nif(msg.topic!=\"\"){ \n\tif(msg.topic.toLowerCase() == \"all\"){\n\t\tfor(var index in context.global) { \n\t\t\tdelete context.global[index];\n\t\t}\n\t} else {\n\t\tfor(var index in context.global) { \n\t\t\tif(index == msg.topic){\n\t\t\t\tdelete context.global[index];\n\t\t\t}\n\t\t}\n\t}\n}","outputs":1,"x":488,"y":197,"z":"1115f4b3.eeea0b","wires":[["870a5c65.78f5a"]]}]

it is an example how to display all ... context.global items on the debug window.
It works for the context which it stores them using this syntax...
context.global.myvar = "foo";

but it does not show items which I stored using this syntax...
global.set('mynewvar','321');

They are different... I cannot use this example to pull up "mynewvar"... so, how can I get the items which are stored in the same context as "mynewvar" to show them on the debug page?

Kind Regards,

Try this

[{"id":"69095e3a.45e6d","type":"function","z":"636437be.db70f8","name":"get global objects","func":"var keys = global.keys();\nvar v,k;\nvar pl = {}\nfor(var i in keys){\n  v = global.get(keys[i])\n  k = keys[i]\n  pl[k] = v\n   \n}\nmsg.payload = pl\nreturn msg;","outputs":1,"noerr":0,"x":420,"y":910,"wires":[["4b166c4d.ba8924"]]},{"id":"4b166c4d.ba8924","type":"debug","z":"636437be.db70f8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":600,"y":910,"wires":[]},{"id":"5f528a20.8991e4","type":"inject","z":"636437be.db70f8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":250,"y":910,"wires":[["69095e3a.45e6d"]]}]

Hi @tree-frog

There are two ways of accessing context. The old way of doing was to access the context.global object directly - such as:

context.global.foo = "bar"; 

That just adds the property to the context.global object in memory and nothing else.

The proper way to access context is to use the get/set functions:

global.set("foo", "bar");

That stores the value in the internal context store - wherever that may be configured to end up.

The example flow you have shared enumerates the properties on the context.global object. That is not the same as enumerating the properties that have been properly set on global context using the set function.

The Context data sidebar lists the properties that have been properly set.

The example from @hotNiPi shows how to achieve much the same result, but by accessing the proper global context object via its get/set/keys api functions.

I used this example to check to see if the values were the same "context", or the same named variable.

[{"id":"c4decc37.7768b","type":"inject","z":"d0ab1f89.619cf","name":"","topic":"","payload":"store 123 into mynewvar","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":760,"wires":[["ef2b6834.f4fd78"]]},{"id":"86b2cb82.282928","type":"inject","z":"d0ab1f89.619cf","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":880,"wires":[["2c12437a.1e4294"]]},{"id":"ef2b6834.f4fd78","type":"function","z":"d0ab1f89.619cf","name":"Global Set mynewvar 123 memoryOnly","func":"global.set('mynewvar','123');\nreturn msg;","outputs":1,"noerr":0,"x":540,"y":760,"wires":[["95bc555c.61225"]]},{"id":"2c12437a.1e4294","type":"function","z":"d0ab1f89.619cf","name":"Global Get mynewvar","func":"var v = global.get('mynewvar');\nmsg.payload= v;\nreturn msg;","outputs":1,"noerr":0,"x":400,"y":880,"wires":[["aa904188.995a3"]]},{"id":"95bc555c.61225","type":"debug","z":"d0ab1f89.619cf","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":830,"y":760,"wires":[]},{"id":"aa904188.995a3","type":"debug","z":"d0ab1f89.619cf","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":750,"y":880,"wires":[]},{"id":"350c554a.8d89d2","type":"inject","z":"d0ab1f89.619cf","name":"","topic":"","payload":"store 321 into mynewvar","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":210,"y":800,"wires":[["a144fe97.6c0498"]]},{"id":"a144fe97.6c0498","type":"function","z":"d0ab1f89.619cf","name":"Context Global mynewvar = 321","func":"context.global.mynewvar ='321';\nreturn msg;","outputs":1,"noerr":0,"x":510,"y":800,"wires":[["fdc732d2.2bb418"]]},{"id":"fdc732d2.2bb418","type":"debug","z":"d0ab1f89.619cf","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":810,"y":800,"wires":[]},{"id":"6f0779e1.5d4a5","type":"inject","z":"d0ab1f89.619cf","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":180,"y":920,"wires":[["fd827e4a.f1bf1"]]},{"id":"fd827e4a.f1bf1","type":"function","z":"d0ab1f89.619cf","name":"payload = Context Global  mynewvar","func":"var v = context.global.mynewvar;\nmsg.payload= v;\nreturn msg;","outputs":1,"noerr":0,"x":450,"y":920,"wires":[["9d119140.7f5db"]]},{"id":"9d119140.7f5db","type":"debug","z":"d0ab1f89.619cf","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":750,"y":920,"wires":[]}]

I redefined my system to default to 'memory' Global variables.

This flow does a few things...

  1. Store a value in a context.global.mynewvar
  2. Store a value in set.global('mynewvar')
  3. Retrieve the content of context.global.mynewvar
  4. Retrieve the content of global.get('mynewvar')

When you set the values to the same variable, you get 2 different results when you write the variable and read the variable data. It is acting like you have 2 different global variables...