Changing global variables

All,

I am new on Node-Red, thus I am sorry if the question is too stupid. I used node-red to build a Chatbot app that uses "text to speech" (voice) capabilities. I have defined a global variable called "speechOnOff", and I set it to "off" initially. As this is a chatbot, I want the users to commands the voice to be on / off by typing a simple sentence "speech on" or "speech off".

My idea is to change the global variable "speechOnOff" dynamically whenever the user commands it.

Is that possible to change a global variable in any function node different form the one I used to set it initially? I tried but I got an error message.

thanks a lot.

Indeed, that is possible and should work. Please detail what is the error message you got so as we can understand and try to help you to find a fix.

1 Like

Thanks a lot Andrei. I declare the variable like that:

NODE 1: Initial Node

var publicVariables = {
    speechOnOff: "Off"
}
global.set("publicVariables", publicVariables);

NODE 2: Then on a second node I test the command, and depending on what it is I set the same global variable to "On" or "Off":

    if (msg.message == "speech on") {
        var publicVariables = {
            speechOnOff: "On"
        }
        global.set("publicVariables", publicVariables);
    }
    else if (msg.message == "speech off") {
        var publicVariables = {
            speechOnOff: "Off"
        }
        global.set("publicVariables", publicVariables);
    }

Finally on third node I checked if the same variable is "on" or "off":

var publicVariables = global.get("publicVariables").publicVariables;
if (publicVariables.speechOnOff == "On") {
    output=msg.payload;
    msg.payload = {};
    msg.payload.output = {text: [output]}
    node.warn(msg.payload.output);
    node.warn("Conversation output is:\n" + JSON.stringify(msg.payload))
    /* node.send([null,msg]); */
    output = msg.payload.output.text.join(' ');
    msg.payload = output;
}

And this is the error I got: TypeError: Cannot read property 'speechOnOff' of undefined, which heppens at the third node.

In your first two nodes, you set publicVariables to be an object that looks like this:

{
   speechOnOff: "on/off"
}

In your third node, you get the property with this:

var publicVariables = global.get("publicVariables").publicVariables;

You are getting the publicVariables global context property and then trying to access a property of that object called publicVariables - which doesn't exist.

So that line should just be:

var publicVariables = global.get("publicVariables");

Thanks a lot. I do not have the error any more. One more question: at the second node, for me to change the value of the global variable, is it correct the code below? I am asking, as it seems the variable is not being changed.

var publicVariables = {
speechOnOff: "On"
}
global.set("publicVariables", publicVariables);

(quick tip, put triple backticks - ``` - before and after any code snippets so that they display properly - I've edited your previous post to add them)

The code is okay - so if it isn't doing what you think, I'd suggest adding some debug statements to check what you're getting. For example, are you sure msg.message is the property to be testing?

var publicVariable;

// log `msg.message` to debug sidebar so you can see what you have
node.warn(msg.message);

if (msg.message == "speech on") {
    publicVariables = {
        speechOnOff: "On"
    }
    global.set("publicVariables", publicVariables);
}
else if (msg.message == "speech off") {
    publicVariables = {
        speechOnOff: "Off"
    }
    global.set("publicVariables", publicVariables);
}

1 Like

Thanks a lot. I will do it. You are great.

Indeed nothing wrong with the code. I tested your second function and it is loading the global variable with an object according to the value of msg.message

r-001

[{"id":"f6a0a4b4.33beb8","type":"tab","label":"Flow 3","disabled":false,"info":""},{"id":"248936c9.f4b12a","type":"debug","z":"f6a0a4b4.33beb8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"check","x":870,"y":360,"wires":[]},{"id":"3cef16e4.3c021a","type":"function","z":"f6a0a4b4.33beb8","name":"Second Function","func":"\nif (msg.message == \"speech on\") {\n    \n    var publicVariables = {\n        speechOnOff: \"On\"\n    }\n    global.set(\"publicVariables\", publicVariables);\n}\nelse if (msg.message == \"speech off\") {\n    \n    var publicVariables = {\n        speechOnOff: \"Off\"\n    }\n    global.set(\"publicVariables\", publicVariables);\n}\nreturn msg;","outputs":1,"noerr":0,"x":550,"y":280,"wires":[["ddc8ec64.70f6"]]},{"id":"975438f6.3aa918","type":"inject","z":"f6a0a4b4.33beb8","name":"","topic":"","payload":"speech on","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":260,"wires":[["3f3265e9.a6205a"]]},{"id":"771aa6ad.91b118","type":"inject","z":"f6a0a4b4.33beb8","name":"","topic":"","payload":"speech off","payloadType":"str","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":300,"wires":[["3f3265e9.a6205a"]]},{"id":"3f3265e9.a6205a","type":"change","z":"f6a0a4b4.33beb8","name":"","rules":[{"t":"set","p":"message","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":330,"y":280,"wires":[["3cef16e4.3c021a"]]},{"id":"ddc8ec64.70f6","type":"function","z":"f6a0a4b4.33beb8","name":"Retrieve value from global context","func":"msg.check = global.get(\"publicVariables\");\nreturn msg;","outputs":1,"noerr":0,"x":640,"y":360,"wires":[["248936c9.f4b12a"]]}]

Thanks Andrei. Much appreciated.