function parsing

6,106 views
Skip to first unread message

matt vorwald

unread,
Jun 16, 2016, 4:42:33 PM6/16/16
to Node-RED
Noob here,

here is the string that i'm passing into my my function

0 16.1 081F 16.1 --  159 146

I want 6 outputs of integers or Boolean

output 1 = 16.1
output 2 = 81
output 3 = 16.1
output 4 = False (Boolean)
output 5 = 159
output 6 = 146


Here is what i have for code in my function

var msg1 = parseFloat(msg.payload.substring(2,6));
var msg2 = parseFloat(msg.payload.substring(7,10));
var msg3 = { payload:"message 3" };
var msg4 = { payload:"message 4" };
var msg5 = { payload:"message 5" };
var msg6 = { payload:"message 6" };
return msg1;

all i'm getting in my debug is  

msg.payload: undefinded
(undefined)

How I've learned this much is from the function tutorial page on node red's website

I'm assuming I'm using the substring java function wrong, or am i just wrong...??  Or is there a node that would be better suited for this action?

Many Thanks in advance.



Dave C-J

unread,
Jun 16, 2016, 5:24:22 PM6/16/16
to node...@googlegroups.com
Hi Matt

each object sent out (msg) should have a property called payload. So each one needs to be like that. Also to send multiple messages out of multiple outputs you need to return it as an array of msg s.
So in the end you need to return [msg1,msg2,msg3,msg4,msg5,msg6];  
and msg1  needs to be  msg1 = {payload:parseFloat(msg.payload.substring(2,6))};
likewise msg2
and similarly for the others....

This should work if the string is always the same length... 
lots of other possibilities... but one step at a time.

Mark Setrem

unread,
Jun 16, 2016, 5:35:11 PM6/16/16
to Node-RED
With that flow you've lost your noob status!


Personally I'd use the split method e.g.  msg.payload.split(" ");   see http://www.w3schools.com/jsref/jsref_split.asp

So
var message1=msg.string[1];// 16.1
var message2=msg.string[2];//081F
var message3=msg.string[3];//16.1
var message4=msg.string[4];//--
var message5=msg.string[5];//159 
var message6=msg.string[6];//146

You would then need to strip the F from message2  which you could do with message2=message2.slice(0, - 1);

Not sure if the False comes from the F or the -- but hopefully you will have enough of an idea.

if you want them as separate messages you would need to declare each of the new msg objects ( e.g. msg2={ }; see the second function example on the nodered website)

Julian Knight

unread,
Jun 16, 2016, 7:57:20 PM6/16/16
to Node-RED
I agree. Split then trim. and the rest as Mark says.

Also, if you want an output message for each element, instead of sending an array of msg object, do a forEach on the split array and use node.send, remove any return msg since it wont be needed as you are sending the msgs yourself. That way, you can reuse the msg object and just change the payload in each loop.

Dave C-J

unread,
Jun 17, 2016, 4:06:23 AM6/17/16
to node...@googlegroups.com
Though he needs to do different things to each part... so a simple split then just use each part probably makes more sense in this case.

matt vorwald

unread,
Jun 17, 2016, 4:05:01 PM6/17/16
to Node-RED
ok, in my head this should spit me out 6 string  messages,  

var msg = { payload: msg.payload.split(" ") };

var message1 = msg.string[1];// 16.1
var message2 = msg.string[2];//081F
var message3 = msg.string[3];//16.1
var message4 = msg.string[4];//--
var message5 = msg.string[5];//159 
var message6 = msg.string[6];//146
return [message1, message2, message3, message4, message5, message6];

Instead i'm getting "TypeError: Cannot read property '1' of undefined"

I get i'm creating a msg array and then we are taking that data and tossing it in the message variables and then returning them.  So i don't get were this error is coming from??

Nicholas O'Leary

unread,
Jun 17, 2016, 4:10:07 PM6/17/16
to Node-RED Mailing List
Hi Matt,

lets take a step back.

1. You are setting msg.payload to be an Array of the split parts of the received msg.payload. You are then trying to reference msg.string which you've not set anywhere.

2. Arrays are indexed from 0, not from 1

3.  A Function node must return message objects. Here you are returning an Array of Strings, not message objects.


So whilst it isn't the most elegant way to do it, here's a corrected version of the approach you're taking:

var parts = msg.payload.split(" ");
var message1 = { payload: parts[0]; }
var message2 = { payload: parts[1]; }
var message3 = { payload: parts[2]; }
var message4 = { payload: parts[3]; }
var message5 = { payload: parts[4]; }
var message6 = { payload: parts[5]; }

--
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.
For more options, visit https://groups.google.com/d/optout.

Mark Setrem

unread,
Jun 17, 2016, 4:21:08 PM6/17/16
to Node-RED
so if you want them as separate messages you first need to declare each of the new message objects

message1 = {};
message2 = {};
message3 = {};
message4 = {};
message5 = {};
message6 = {};

Then you deal with a property of an object so in your line you take the output of splitting msg.payload and make that msg.payload.

But in your lines that follows you are dealing with msg.string rather than msg.payload, so to only change 1 line it should be...

msg.string = msg.payload.split(" ");

then if you want to pass them on each as a separate path you should be dealing with a property of an object not the object itself.  ( e.g. msg.payload not msg), which are the objects you declared at the beginning

message1.payload=msg.string[1];// 16.1
message2.payload=msg.string[2];//081F.
message3.payload=msg.string[3];//16.1
message4.payload=msg.string[4];//--
message5.payload=msg.string[5];//159 
message6.payload=msg.string[6];//146


[{"id":"fa8dc348.05724","type":"inject","z":"156ca245.ea935e","name":"","topic":"","payload":"\"0 16.1 081F 16.1 --  159 146\"","payloadType":"str","repeat":"","crontab":"","once":false,"x":123.5,"y":112,"wires":[["161f6bb1.e9e094"]]},{"id":"161f6bb1.e9e094","type":"function","z":"156ca245.ea935e","name":"","func":"message1 = {};\nmessage2 = {};\nmessage3 = {};\nmessage4 = {};\nmessage5 = {};\nmessage6 = {};\n\nmsg.string = msg.payload.split(\" \");\n\nmessage1.payload=msg.string[1];// 16.1\nmessage2.payload=msg.string[2];//081F\nmessage3.payload=msg.string[3];//16.1\nmessage4.payload=msg.string[4];//--\nmessage5.payload=msg.string[5];//159 \nmessage6.payload=msg.string[6];//146\n\n\n\nreturn [message1, message2, message3, message4, message5, message6];\n\n\n\n\n\n\n\nreturn msg;","outputs":"6","noerr":0,"x":272.5,"y":116,"wires":[["d4a6f2f4.2b591"],["d4a6f2f4.2b591"],["d4a6f2f4.2b591"],["d4a6f2f4.2b591"],["d4a6f2f4.2b591"],["d4a6f2f4.2b591"]]},{"id":"d4a6f2f4.2b591","type":"debug","z":"156ca245.ea935e","name":"","active":true,"console":"false","complete":"false","x":479.5,"y":109,"wires":[]}] 

matt vorwald

unread,
Jun 17, 2016, 4:44:41 PM6/17/16
to Node-RED
So this way would use no array, which is fine.  Thanks for the help!

However, 

var message = { payload: msg.payload.split(" ") };
return message;

returns in one output  [ "0", "16.1", "081F", "16.1", "--", "", "159", "146" ] which is basically printing the array.

why can't i just return each value by just going to the doing return message[1], message[2]; and have them pop out on their respective outputs?

matt vorwald

unread,
Jun 17, 2016, 5:10:45 PM6/17/16
to Node-RED
in the flow you sent me message 5 has a no value and then message 6 has 5's value and message 6 never gets printed.

???

Nicholas O'Leary

unread,
Jun 17, 2016, 5:12:26 PM6/17/16
to Node-RED Mailing List
Hi Matt,

you cannot return individual strings - you must return message objects.

Nick

--

Mark Setrem

unread,
Jun 17, 2016, 5:30:50 PM6/17/16
to Node-RED
yep trying to answer whilst also doing something else.

caused by your input having multiple spaces after the --

if you google for "javascript splitting string on multiple spaces" I'm sure you'll find a quick fix

matt vorwald

unread,
Jun 20, 2016, 3:25:51 PM6/20/16
to Node-RED
Got it hammered out w/ a little help from the node red doc page


//split string using spaces and put into aray outputMsgs
var outputMsgs = [];
var words = msg.payload.split(" ");
for (var w in words) {
    outputMsgs.push({payload:words[w]});
}

//clean up data and make real #'s
outputMsgs[1].payload = parseFloat(outputMsgs[1].payload);
outputMsgs[2].payload = outputMsgs[2].payload.slice(0, -1);
outputMsgs[2].payload = parseFloat(outputMsgs[2].payload);
outputMsgs[3].payload = parseFloat(outputMsgs[3].payload);
outputMsgs[6].payload = parseFloat(outputMsgs[6].payload);
outputMsgs[7].payload = parseFloat(outputMsgs[7].payload);

//return values 
return outputMsgs;

Cotsios

unread,
Mar 13, 2017, 6:30:45 AM3/13/17
to Node-RED
I know this is old, but this could help others:

You can use substr() method instead. This method seems to work in NodeRed.

Reply all
Reply to author
Forward
0 new messages