loop thru json array and set them as global

1,853 views
Skip to first unread message

Roger

unread,
Oct 2, 2017, 5:49:24 PM10/2/17
to Node-RED
I read an array from a webpage
Then i want to store the values to globals
To do this i think about running a loop and use the index to identify the globals

what i have done now is
var json = msg.payload;

for (var i in json) {
if (json.hasOwnProperty(i)) {
  msg.id(json[i].X)=(json[i].X);
  msg.lat(json[i].Y)=(json[i].Y);
}
}

return msg;

but thats not working

any tips how to do this in the right way?

Roger

unread,
Oct 2, 2017, 6:00:37 PM10/2/17
to Node-RED
i added this
node.send({payload:msg.id});

that gives my output and show its working ;-)

but is it possible to do something like
global.set("name"+msg.id,value);

at least now it is not working...

Colin Law

unread,
Oct 3, 2017, 3:26:52 AM10/3/17
to node...@googlegroups.com
On 2 October 2017 at 23:00, Roger <rog...@qusax.eu> wrote:
> i added this
> node.send({payload:msg.id});
>
> that gives my output and show its working ;-)
>
> but is it possible to do something like
> global.set("name"+msg.id,value);

That should be
global.set("name", msg.id.value)
then use
global.get("name")
to fetch the value later.

See https://nodered.org/docs/writing-functions

However I suggest you first really convince yourself that you want to
use the global context. Sometimes it is the right thing to do but
often it is not the best. Consider whether it would be better to pass
messages containing the data to the nodes that need it instead of
using global. Initially it may seem like the easy way but often it
ends up more complex and more difficult to follow what is happening in
the flow.

Colin

>
> at least now it is not working...
>
> --
> http://nodered.org
>
> Join us on Slack to continue the conversation: http://nodered.org/slack
> ---
> You received this message because you are subscribed to the Google Groups
> "Node-RED" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to node-red+u...@googlegroups.com.
> To post to this group, send email to node...@googlegroups.com.
> Visit this group at https://groups.google.com/group/node-red.
> To view this discussion on the web, visit
> https://groups.google.com/d/msgid/node-red/9b802de6-4c2b-4798-8f54-d164b9f0019a%40googlegroups.com.
>
> For more options, visit https://groups.google.com/d/optout.

Roger

unread,
Oct 3, 2017, 4:57:09 AM10/3/17
to Node-RED
global.set("name", msg.id.value) 
then use 
global.get("name") 
to fetch the value later. 

clear, but how can i add the index to the variable?
So i get name1, name2 etc...

Maybe a good idea to skip the global.
But on start i get data from the database and then the coming hour i need this data
Is there another way to use this data?
Or should i store the whole string in 1 global?

Thanks for your advice!


Op dinsdag 3 oktober 2017 09:26:52 UTC+2 schreef Colin Law:

Mark Setrem

unread,
Oct 3, 2017, 5:13:07 AM10/3/17
to Node-RED

you can add dynamic content to the name of a global variable.

e.g. 

global.set("name"+msg.topic,msg.payload);

[{"id":"7f755270.8a6fc4","type":"inject","z":"68f1ee9d.501428","name":"","topic":"thetopic","payload":"test","payloadType":"str","repeat":"","crontab":"","once":false,"x":116.5,"y":134,"wires":[["d7b43898.7662c8"]]},{"id":"d7b43898.7662c8","type":"function","z":"68f1ee9d.501428","name":"set global","func":"\nglobal.set(\"name\"+msg.topic,msg.payload);\n\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":120,"wires":[[]]},{"id":"4b9211cd.50034","type":"inject","z":"68f1ee9d.501428","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":120,"y":200,"wires":[["f93661d8.0960a8"]]},{"id":"f93661d8.0960a8","type":"function","z":"68f1ee9d.501428","name":"get global","func":"\nmsg.payload = global.get(\"namethetopic\");\n\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":200,"wires":[["adb331f7.25bbe"]]},{"id":"adb331f7.25bbe","type":"debug","z":"68f1ee9d.501428","name":"","active":true,"console":"false","complete":"false","x":410,"y":200,"wires":[]}]

steve rickus

unread,
Oct 3, 2017, 8:26:41 AM10/3/17
to Node-RED
If you really need to use the same list of names for an hour, you will need to persist the array somewhere (file, database, context, etc). Where is the list of names coming from? If it's already in a database, then it makes less sense to persist it again... if you are able to share your flow, there are people here who can offer alternative suggestions.

So assuming you need to save an array of names in context, you will need to decide which context to use (node, flow, or global). If the list is only used inside your one function node, use the node's context -- if only by nodes within the same tab on the editor, then use flow context. As Colin says, use the global context as little as possible, especially since all the variable names must be unique across all your flows and all time. Using "name1", "name2" may work for now, but is risky.

Incidentally, you can put the entire array of names into a single context variable, which is the way I would handle it. Then when you get the array back to use later, you can access the elements by their index number, and not some string with the index # appended to it -- much easier to handle, imo.
--
Steve

Roger

unread,
Oct 3, 2017, 3:04:16 PM10/3/17
to Node-RED
Clear! Thanks Steve!

Op dinsdag 3 oktober 2017 14:26:41 UTC+2 schreef steve rickus:

Roger

unread,
Oct 3, 2017, 3:06:31 PM10/3/17
to Node-RED
global.set is working nice this way

but fighting now to load them in a loop like this 
for ( i = 1; i <= steps; i++ ){
    var step(i) = global.get("step" + i);
}

cannot find out how to set the index i to the var stepX

tried +,  .  , [i]


Op dinsdag 3 oktober 2017 11:13:07 UTC+2 schreef Mark Setrem:

Nick O'Leary

unread,
Oct 3, 2017, 3:30:40 PM10/3/17
to Node-RED Mailing List
Roger,

there isn't quite enough information in that snippet of code to fully help.

for ( i = 1; i <= steps; i++ ){
    var step(i) = global.get("step" + i);
}

What are you trying to do in that loop? What do you want out at the end?

var step(i)... is not valid javascript, but without a better sense of what you're trying to do, its hard to suggest what it should be.



--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+unsubscribe@googlegroups.com.

To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

Roger

unread,
Oct 3, 2017, 3:37:33 PM10/3/17
to Node-RED
What i try to do is call multiple globals that i have set in another flow with this loop
var steps = 5;

for ( i = 1; i <= steps; i++ ){
    global.set("step"+i,1);
}

In another flow i want to call them, i can write 
var step1 = global.get("step1");
var step2 = global.get("step2");
var step3 = global.get("step3");
var step4 = global.get("step4");
var step5 = global.get("step5");

but i want to do this in a loop because "steps" variates
What i tried is this.
Loop thru each global and make a variable
for ( i = 1; i <= steps; i++ ){
    var step(i) = global.get("step" + i);
}

Is this more clear this way?


Op dinsdag 3 oktober 2017 21:30:40 UTC+2 schreef Nick O'Leary:
Roger,

there isn't quite enough information in that snippet of code to fully help.

for ( i = 1; i <= steps; i++ ){
    var step(i) = global.get("step" + i);
}

What are you trying to do in that loop? What do you want out at the end?

var step(i)... is not valid javascript, but without a better sense of what you're trying to do, its hard to suggest what it should be.


On 3 October 2017 at 20:06, Roger <rog...@qusax.eu> wrote:
global.set is working nice this way

but fighting now to load them in a loop like this 
for ( i = 1; i <= steps; i++ ){
    var step(i) = global.get("step" + i);
}

cannot find out how to set the index i to the var stepX

tried +,  .  , [i]


Op dinsdag 3 oktober 2017 11:13:07 UTC+2 schreef Mark Setrem:

you can add dynamic content to the name of a global variable.

e.g. 

global.set("name"+msg.topic,msg.payload);

[{"id":"7f755270.8a6fc4","type":"inject","z":"68f1ee9d.501428","name":"","topic":"thetopic","payload":"test","payloadType":"str","repeat":"","crontab":"","once":false,"x":116.5,"y":134,"wires":[["d7b43898.7662c8"]]},{"id":"d7b43898.7662c8","type":"function","z":"68f1ee9d.501428","name":"set global","func":"\nglobal.set(\"name\"+msg.topic,msg.payload);\n\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":120,"wires":[[]]},{"id":"4b9211cd.50034","type":"inject","z":"68f1ee9d.501428","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":120,"y":200,"wires":[["f93661d8.0960a8"]]},{"id":"f93661d8.0960a8","type":"function","z":"68f1ee9d.501428","name":"get global","func":"\nmsg.payload = global.get(\"namethetopic\");\n\nreturn msg;","outputs":1,"noerr":0,"x":280,"y":200,"wires":[["adb331f7.25bbe"]]},{"id":"adb331f7.25bbe","type":"debug","z":"68f1ee9d.501428","name":"","active":true,"console":"false","complete":"false","x":410,"y":200,"wires":[]}]

--
http://nodered.org
 
Join us on Slack to continue the conversation: http://nodered.org/slack
---
You received this message because you are subscribed to the Google Groups "Node-RED" group.
To unsubscribe from this group and stop receiving emails from it, send an email to node-red+u...@googlegroups.com.

To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

Nick O'Leary

unread,
Oct 3, 2017, 3:40:34 PM10/3/17
to Node-RED Mailing List
Ok, you can't dynamically generate a variable name like that:

   var step(i) = ... 

So you have a few different options.

Perhaps the easiest is to create a local array of them:

var values = [];
for ( var i = 1; i <= steps; i++ ){
    values[i] = global.get("step" + i);
}

You can then use values[1] , values[2] etc

Nick


To unsubscribe from this group and stop receiving emails from it, send an email to node-red+unsubscribe@googlegroups.com.

To post to this group, send email to node...@googlegroups.com.
Visit this group at https://groups.google.com/group/node-red.

Roger

unread,
Oct 3, 2017, 3:42:34 PM10/3/17
to Node-RED
Okidoki, clear. 
Thanks Nick!

Op dinsdag 3 oktober 2017 21:40:34 UTC+2 schreef Nick O'Leary:

Colin Law

unread,
Oct 3, 2017, 4:34:30 PM10/3/17
to node...@googlegroups.com
It is possible to save a complete array to the context, I am not sure
exactly what you are doing, but if you built an array of the values
you could save the whole array in one item. Then you wouldn't have to
mess about getting them one at a time.

Colin
> https://groups.google.com/d/msgid/node-red/e2398c0e-b105-434c-ad78-a1d881d2ce3e%40googlegroups.com.

steve rickus

unread,
Oct 3, 2017, 4:42:49 PM10/3/17
to Node-RED
Once again I need to point out how much easier it would be to just keep this whole array of "steps" in a single global context variable...
Instead of appending the index # to the variable name, just use standard javascript array syntax to set and get elements in the array.

So in the "building the array" function, you can do something like this:

var stepCount = 5;
var stepArray = []; // start with an empty array

// array indexes start at 0
for (var i = 0; i < stepCount; i++) {
    stepArray
[i] = i + 1;
    console
.log("set step #" + stepArray[i]);
}

// now save the whole array to global context
global.set("MySteps", stepArray);

Then, in the "using the array" function, you can do this:

// get the array of steps, or an empty array (if not found)
var steps = global.get("MySteps") || [];

for (var i = 0; i < steps.length; i++) {
    node
.send({payload: steps[i]}); // or do something else with each step
    console
.log("get step #" + steps[i]);
}
return null;

If you have not been through the javascript array methods on the W3Schools site (links above), it may help to understand how they work. I rarely use the looping syntax like this, because I find the array methods like find(), forEach(), map(), reduce(), filter(), etc simpler to use and more concise.
--
Steve
Reply all
Reply to author
Forward
0 new messages