How to write code to point to/get message subparts?

I am writing this as I am on another quest to try and get my head around how to do something.

Taking it to basics - the flow:

[{"id":"75a8babad6400d8f","type":"inject","z":"7e987ddf260bdf0d","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":4180,"y":2310,"wires":[["47405ea11fe09c0c"]]},{"id":"47405ea11fe09c0c","type":"function","z":"7e987ddf260bdf0d","name":"Example 2","func":"msg = { \"WIFI_DEVICE\": \"TelePi\", \"IP_Address\": \"192.168.0.93\", \"Sent\": \"2022-04-27 07:24:54\" };\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":4350,"y":2310,"wires":[["6b24df8a1f645f03","50fe4009ba4846bf"]]},{"id":"6b24df8a1f645f03","type":"function","z":"7e987ddf260bdf0d","name":"","func":"let x = \"WIFI_DEVICE\";\nlet y = \"msg.\"+x;\nnode.warn(y);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":4520,"y":2310,"wires":[[]]}]

The message being sent in is this (example)
{"WIFI_DEVICE":"TelePi","IP_Address":"192.168.0.93","Sent":"2022-04-27 07:24:54","_msgid":"bf56e1984a7c7ab2"}

In the second function node I want to define which sub part of the message I want to get/see.

Alas rather than getting the value, I get the path.

This may be easier to explain:

let x = "WIFI_DEVICE";
let y = "msg."+x;
node.warn(y);
return msg;

x is the path I create the path name (let y = "msg."+x) but then I get that echoed to me.
I want to see the value of where that is pointing. (I think is the term)

So I should get TelePi.

Efforts:

let x = "WIFI_DEVICE";
let y = "msg."+x;
node.warn(y);  // a
node.warn(msg.WIFI_DEVICE);  // b
node.warn(msg.x);  // c
return msg;

a gets what I've shown.
b works.
c doesn't.
Trying to .... concatenate the msg. and x isn't working if I put a + sign.

Ok, maybe I am wrong with one of those... I'm working on it now, in real time.
It's impossible to keep the thread up to date with what is happening now.

I'm asking if someone could confirm how to do this before I go any more batty than I already am. :wink:

Use square bracket notation...

const part="payload"
let p = msg[part]
msg[part] = 123
1 Like

Of course! Silly me!

And in the mean time I have found another way of doing it. Messy.... But....

But now I know this, I'll keep things simple and do it that way.

Argh! I should have known that.

Thanks mate.

Hey Steve.....

It did work, but it also doesn't work.

I think I oversimplified the example as the initial tests after you showed me did work.

But now I am onto the REAL application it is back to not wanting to play the game.

This is the payload I am using now - which is a bit more complex (I suspect) than the original one.

{"topic":"STATUS/WIFIDEVICEID","payload":{"WIFI_DEVICE":"TelePi","IP_Address":"192.168.0.93","Sent":"2022-04-28 08:18:58"},"qos":0,"retain":false,"_msgid":"31994a5118c3e254"}

(This has payload and nested stuff in it.)

This is a screen shot of what I see:

Screenshot from 2022-04-28 08-46-28

To maybe help with that this is an exert from the code:


let part = env.get("msg_part_to_scan");
if (part.length < 1)
    throw "You must define which part of the message to scan";
//------------------

if (debug == 1)
    node.warn("Part is set to " + part);   //  You see this in the green box above.

//  Set `newval` from incoming message.
newval = msg[part];     //  Extract the desired part of the message.

if (debug == 1)
{
    node.warn("100 Mode is set to " + mode);
    node.warn("101 control_topic is set to " + CTLTopic);
    node.warn("102 Incoming message for checking is " + newval);
    node.warn("103 topic_mode is set to " + topic_mode);
    node.warn("104 Topic is " + topic);
}

Yet 102 isn't happy with what newval is.
But I'm guessing it is failing where/when it gets it's assignment.
newval = msg[part]

Seems I am still missing an elephant in the room somewhere.

Oh

(For anyone)

Here are the two example flows.
Top works, bottom one doesn't.

[{"id":"e4726afe26a31f7e","type":"inject","z":"7e987ddf260bdf0d","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":4260,"y":3230,"wires":[["295950a9264e5196"]]},{"id":"295950a9264e5196","type":"function","z":"7e987ddf260bdf0d","name":"Example 2","func":"msg = { \"WIFI_DEVICE\": \"TelePi\", \"IP_Address\": \"192.168.0.93\", \"Sent\": \"2022-04-27 07:24:54\" };\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":4430,"y":3230,"wires":[["8d19384085c188b1"]]},{"id":"8d19384085c188b1","type":"function","z":"7e987ddf260bdf0d","name":"","func":"let x = \"WIFI_DEVICE\";\nlet y = msg[x];\nnode.warn(y);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":4600,"y":3230,"wires":[[]]},{"id":"0679f0af6fcb63c2","type":"inject","z":"7e987ddf260bdf0d","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":4260,"y":3290,"wires":[["a43b64bf445f3611"]]},{"id":"a43b64bf445f3611","type":"function","z":"7e987ddf260bdf0d","name":"","func":"msg = {\"topic\":\"STATUS/WIFIDEVICEID\",\"payload\":{\"WIFI_DEVICE\":\"TelePi\",\"IP_Address\":\"192.168.0.93\",\"Sent\":\"2022-04-28 08:18:58\"},\"qos\":0,\"retain\":false,\"_msgid\":\"a90103fd34a05c17\"};\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":4420,"y":3290,"wires":[["5cdb79b33aab4766"]]},{"id":"5cdb79b33aab4766","type":"function","z":"7e987ddf260bdf0d","name":"","func":"let x = \"payload.WIFI_DEVICE\";\nlet y = msg[x];\nnode.warn(y);\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":4600,"y":3290,"wires":[[]]}]

You are trying to access sub element of payload named WIFI_DEVICE...
image

This is NOT how bracket notation works.

To use bracket notation with multiple levels, you would need to split the string & loop the parts to reach the 2nd level element

e.g. msg[first_level][second_level] which is the same as msg["payload"]["WIFI_DEVICE"] or msg.payload.WIFI_DEVICE

Fortunately, there is a helper utility function built into node-red...

chrome_9Eg7I88izq

RED.util.getMessageProperty

1 Like

@Steve-Mcl

Thanks.

Sorry for sort of misdirecting you with the previous example which was kind of correct but also flawed because I didn't realise things were that complicated.

I rolled out the first solution and wondered why as much as some were working: others weren't.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.