How to add new level in Json global context file

Hello,
I'm new in node-red univers, sorry if I ask basic questions....
I would like to add a new level in the global.json file from a JS function node.

I would like my global.json looks like that :

{
   "A":{
      "1":{
          "info_1":"true",
          "info_2":"false",
          "info_3":"false"
           },
      "2":{
          "info_1":"false",
          "info_2":"false",
          "info_3":"true"
           }
   },
   "B":{
      "1":{
          "info_1":"true",
          "info_2":"false",
          "info_3":"false"
           },
      "2":{
          "info_1":"false",
          "info_2":"false",
          "info_3":"true"
           }
   }
}

How can I add new level in this file like for exemple a third level in "A" ?

"3":{
          "info_1":"false",
          "info_2":"false",
          "info_3":"true"
           }

To have :

{
   "A":{
      "1":{
          "info_1":"true",
          "info_2":"false",
          "info_3":"false"
           },
      "2":{
          "info_1":"false",
          "info_2":"false",
          "info_3":"true"
           },
       "3":{
          "info_1":"false",
          "info_2":"false",
          "info_3":"true"
           }
   },
   "B":{
      "1":{
          "info_1":"true",
          "info_2":"false",
          "info_3":"false"
           },
      "2":{
          "info_1":"false",
          "info_2":"false",
          "info_3":"true"
           }
   }
}

Hoping to have been clear...
Thank you

Sorry for my English, I'm French..

This is the global context store, so you can use the global.set() function to write whatever values you want.

For example:

var currentValue = global.get("A");
currentValue["3"] = {
    "info_1":"false",
    "info_2":"false",
    "info_3":"true"
}
global.set("A",currentValue);

The docs for working with context in the Function node are here: https://nodered.org/docs/user-guide/writing-functions#storing-data

Thank you for the answer, when i do that i have that error :
TypeError: Cannot set property '3' of undefined

How did you set the contents of global.json to being with?

I have assumed this is the global context file store and you have enabled file-based persistence of context. If that is not the case, and this global.json file is something you've created yourself, then please describe what you have done.

This is my code in a JS Node wich is connected to a MQTT input Node.

var topic=msg.topic;
var value=msg.payload;
var array = topic.split("/");
var chambre = array[0];
var type = array[1];
var etage

msg.payload={"chambre":chambre,"type":type,"value":value};

if (chambre != "general"){

var num_ch_etage = parseInt(msg.payload.chambre || 0);
if (num_ch_etage > 1 && num_ch_etage < 99){
	etage = "RDC";
}
if (num_ch_etage > 101 && num_ch_etage < 199){
	etage = "R+1";
}
if (num_ch_etage > 201 && num_ch_etage < 299){
	etage = "R+2";
}
if (num_ch_etage > 301 && num_ch_etage < 399){
	etage = "R+3";
}


var object = {
     [chambre] : {
		alarme:"",
		etat_systeme:"",
		adresse_ip:"",
		SoftVersion:"",
		capteur_lit:"",
		capteur_porte:"",
		nom:"",
		trame_vie:"",
		num_chambre: chambre
	 }
}

msg.payload=global.get(chambre);
if (msg.payload === undefined){
    global.set(etage,object,"file");
}
msg.payload=global.get(chambre);

var alarme = msg.payload.alarme;
var etat_systeme = msg.payload.etat_systeme;
var adresse_ip = msg.payload.adresse_ip;
var SoftVersion = msg.payload.SoftVersion;
var capteur_porte = msg.payload.capteur_porte;
var capteur_lit = msg.payload.capteur_lit;
var nom = msg.payload.nom;
var trame_vie = msg.payload.trame_vie;
var num_chambre = msg.payload.num_chambre;

if (type=="alarme"){
    if (value!=alarme){
        msg.payload.alarme=value;
        object=msg.payload;
        global.set(etage,object,"file");
    }
}

if (type=="etat_systeme"){
    if (value!=etat_systeme){
        msg.payload.etat_systeme=value;
        object=msg.payload;
        global.set(etage,object,"file");
    }
}

if (type=="adresse_ip"){
    if (value!=adresse_ip){
        msg.payload.adresse_ip=value;
        object=msg.payload;
        global.set(etage,object,"file");
    }
}

if (type=="SoftVersion"){
    if (value!=SoftVersion){
        msg.payload.SoftVersion=value;
        object=msg.payload;
        global.set(etage,object,"file");
    }
}

if (type=="capteur_porte"){
    if (value!=capteur_porte){
        msg.payload.capteur_porte=value;
        object=msg.payload;
        global.set(etage,object,"file");
    }
}

if (type=="capteur_lit"){
    if (value!=capteur_lit){
        msg.payload.capteur_lit=value;
        object=msg.payload;
        global.set(etage,object,"file");
    }
}

if (type=="nom"){
    if (value!=nom){
        msg.payload.nom=value;
        object=msg.payload;
        global.set(etage,object,"file");
    }
}

if (type=="trame_vie"){
    if (value!=trame_vie){
        msg.payload.trame_vie=value;
        object=msg.payload;
        global.set(etage,object,"file");
    }
}

if (type=="num_chambre"){
    if (value!=num_chambre){
        msg.payload.num_chambre=value;
        object=msg.payload;
        global.set(etage,object,"file");
    }
}

msg.payload=global.get(chambre);

}
return msg;

This is my global.json file :

{
    "RDC": {
        "002": {
            "alarme": "",
            "etat_systeme": "",
            "adresse_ip": "",
            "SoftVersion": "",
            "capteur_lit": "",
            "capteur_porte": "",
            "nom": "",
            "trame_vie": "",
            "num_chambre": "002"
        }
    },
    "R+1": {
        "102": {
            "alarme": "",
            "etat_systeme": "",
            "adresse_ip": "",
            "SoftVersion": "",
            "capteur_lit": "",
            "capteur_porte": "",
            "nom": "",
            "trame_vie": "",
            "num_chambre": "102"
        }
    }
}

but i have this error :

TypeError: Cannot read property 'alarme' of undefined

So this was the missing information - you are using a non-default store for context - "file". The code I provided didn't know you were doing that so didn't specify the right context store.

Did you try changing the code I provided to use the same store?

var currentValue = global.get("A","file");
currentValue["3"] = {
    "info_1":"false",
    "info_2":"false",
    "info_3":"true"
}
global.set("A",currentValue,"file");

In fact, I can see you code doesn't use "file" consistently:

Here you get the value from default context identified by the value of chambre. You check if it is undefined and then set something in file context.
You then get the chambre object back from normal context and use it, ignoring the fact it may be undefined.

I modify the code to always use file context but i still have the same error

msg.payload=global.get(chambre,"file");
if (msg.payload === undefined) {
   global.set(etage,object,"file");
}
msg.payload=global.get(chambre"file");

Line 1 gets the value.
Line 2 checks the value is undefined and if it is, sets a different property in context
Line 3 gets the value again - same as Line 1.

You have code in line 2 that handles the case if msg.payload is undefined, but it leaves msg.payload undefined. So when you try to reference msg.payload.alarme you get the error because msg.payload is undefined.

global.get(chambre,"file") can be traduct by global.get("002","file") if we don't use variable.

"002" is a sub-object in my global.json file how can I get this sub-object ? should I
specify in which object is my sub-oject ? Cause "002" is the sub-objet of "RDC".

does there is a syntaxe to do this ? like global.get("RDC","002","file") ??

No idea please ? I'm stuck.
When I use global.get("RDC") I get all sub-objects but I can't do msg.payload.002 or
msg.payload.chambre (chambre is a variable)

If you do global.get("RDC") and want to access the 002 level under it, you should be able to do:

var prop = global.get("RDB","file");
var subProp = prop["002"];
//or
var subProp2 = prop[chambre];

Or you could do:

var subProp = global.get("RBD.002","file");

Thank you,

And can I do this ? :

var etage ="RDC";
var chambre = "002";
var subProp = global.get(etage.chambre,"file");

No, that is not valid javascript.

You need to build the string "RDB.002":

var etage ="RDC";
var chambre = "002";
var subProp = global.get(etage+"."+chambre,"file");

When I use your code it works but when I use mine I got an error

MQTT sending this : 102/alarme payload : "1"

My code :

var topic=msg.topic;
var value=msg.payload;
var array = topic.split("/");
var chambre = array[0];
var type = array[1];
var etage

msg.payload={"chambre":chambre,"type":type,"value":value};


var num_ch_etage = parseInt(msg.payload.chambre || 0);
if (num_ch_etage > 1 && num_ch_etage < 99){
	etage = "RDC";
}
if (num_ch_etage > 101 && num_ch_etage < 199){
	etage = "R+1";
}
if (num_ch_etage > 201 && num_ch_etage < 299){
	etage = "R+2";
}
if (num_ch_etage > 301 && num_ch_etage < 399){
	etage = "R+3";
}

var subProp = global.get(etage+"."+chambre,"file");

msg.payload=subProp

return msg;

the error : 102/alarme : msg.payload : undefined

Add some node.warn(“debug1=“+some_variable); in your code to dump info to the debug. That way you can see what is happening in your code.

Where should i put that in my code ? I got an error when I add this line

SyntaxError: Invalid or unexpected token

Ok I found an error in my global.json file when i make tests...

var subProp = global.get(etage+"."+chambre,"file");

That works good ! Thank you a lot @knolleary

I hope you didn't just copy/paste it, you would need to make sure the double quotes are not 'smart' double quotes and change some_variable to the variable you want to display

No I didn't copy/past I changed some_variable but I don't really know which variable use...

I got [warn] [function:18921846.d1d798] debug1=

but nothing more...

But I resolve my error so I don't really need this command ...

you could have used

var topic=msg.topic;
var value=msg.payload;
var array = topic.split("/");
var chambre = array[0];
var type = array[1];
var etage

node.warn(“value=“+value);
node.warn(“ array =“+ array);

anything you want. It's just a way of seeing what yo are working and if the logic of you function is working the way you want it to or the way you told it to. :laughing: