Dynamic Objectpath for extracting an element

Hi all!

I want to extract a message element by a known path, but dynamically (via dropwdown or inputstring).
How can I do this?

Thanks for help on this!

If the element path is in the variable path then you can use msg[path] to address that element in the message.

I'm not sure understanding you right, but the [path] should be user definable and not hardcoded.

image

I want the user to let him choose, wich parameter he wants to see visualized of a large dataset.

path is a variable which you got from the input string. So if that is in the payload and your object is in msg.JsonDatset__DataCycleModuleDataset then you can use, in a Function node
msg.JsonDatset__DataCycleModuleDataset[msg.payload]

This should work:

var userinput = "measureDataset.measureData[0].cellsensitivity"
msg.payload = msg.JsonDataset__DataCycleModuleDataset[userinput]

But you will presumably have to devise a way to translate a simple user selection such as "Sensitivity" into "measureDataset.measureData[0].cellsensitivity"

Sounds good, but is not working...

Please export that flow so that we can try it ourselves. See this post how to post a flow - How to share code or flow json

[{"id":"7f526c4d.e81224","type":"debug","z":"193cbcd5.135b83","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":430,"y":520,"wires":[]},{"id":"c647637b.689c1","type":"inject","z":"193cbcd5.135b83","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"Timestamp__DataCycleModuleDataset\":\"2021-09-09T06:45:45.580Z\",\"ModuleIndex\":3,\"ModuleOk\":true,\"JsonDataset__DataCycleModuleDataset\":{\"measureDataset\":{\"encodingMask\":1,\"ok\":true,\"supplyVoltage\":5.01016976,\"remark\":null,\"temperatureActual\":22,\"measureData\":[{\"bridgeNr\":1,\"cellOffset\":-3.93310546875,\"cellOffsetOk\":true,\"cellSensitivity\":1.7035264726429749,\"cellSensitivityOk\":true,\"pressures\":[{\"encodingMask\":3,\"nr\":1,\"pressureTarget\":0.5,\"pressureActual\":0.4987254,\"pressureRegister\":19032,\"temperatureRegister\":16144,\"ntcRegister\":0,\"chipTemperatureRegister\":15552,\"diodeRegister\":16148,\"outputValue\":0,\"outputValueNormed\":0,\"outputValueDiff\":0,\"outputValueDiffNormed\":0,\"pressureDataOk\":true,\"pressureActualOk\":true,\"chipTemperatureRegisterOk\":true,\"outputValueNormedOk\":null,\"outputValueDiffNormedOk\":null},{\"encodingMask\":3,\"nr\":1,\"pressureTarget\":1.8,\"pressureActual\":1.797337,\"pressureRegister\":11783,\"temperatureRegister\":16148,\"ntcRegister\":0,\"chipTemperatureRegister\":15556,\"diodeRegister\":16148,\"outputValue\":0,\"outputValueNormed\":0,\"outputValueDiff\":0,\"outputValueDiffNormed\":0,\"pressureDataOk\":true,\"pressureActualOk\":true,\"chipTemperatureRegisterOk\":true,\"outputValueNormedOk\":null,\"outputValueDiffNormedOk\":null}],\"pressuresMeasureOk\":true},{\"bridgeNr\":2,\"cellOffset\":1.71234130859375,\"cellOffsetOk\":true,\"cellSensitivity\":1.6407810500749416,\"cellSensitivityOk\":true,\"pressures\":[{\"encodingMask\":3,\"nr\":2,\"pressureTarget\":0.5,\"pressureActual\":0.4987254,\"pressureRegister\":10773,\"temperatureRegister\":16168,\"ntcRegister\":0,\"chipTemperatureRegister\":15552,\"diodeRegister\":16168,\"outputValue\":0,\"outputValueNormed\":0,\"outputValueDiff\":0,\"outputValueDiffNormed\":0,\"pressureDataOk\":true,\"pressureActualOk\":true,\"chipTemperatureRegisterOk\":true,\"outputValueNormedOk\":null,\"outputValueDiffNormedOk\":null},{\"encodingMask\":3,\"nr\":2,\"pressureTarget\":1.8,\"pressureActual\":1.797337,\"pressureRegister\":17755,\"temperatureRegister\":16168,\"ntcRegister\":0,\"chipTemperatureRegister\":15556,\"diodeRegister\":16168,\"outputValue\":0,\"outputValueNormed\":0,\"outputValueDiff\":0,\"outputValueDiffNormed\":0,\"pressureDataOk\":true,\"pressureActualOk\":true,\"chipTemperatureRegisterOk\":true,\"outputValueNormedOk\":null,\"outputValueDiffNormedOk\":null}],\"pressuresMeasureOk\":true}],\"measureOk\":true,\"supplyVoltageOk\":true},\"dataValidation\":{\"dataChangeId\":637667667711844900,\"dataCRC\":0},\"cycleTime\":25601.914,\"timestampEntry\":\"2021-09-09T06:45:45.5796704Z\",\"index\":3,\"objMessage\":{\"locale\":null,\"text\":null},\"message\":{\"locale\":null,\"text\":null},\"modulPartCycleQuality\":1}}","payloadType":"json","x":150,"y":520,"wires":[["7f526c4d.e81224","6581831c.51f63c"]]},{"id":"77c84f3f.8f4b3","type":"debug","z":"193cbcd5.135b83","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":410,"y":720,"wires":[]},{"id":"6581831c.51f63c","type":"function","z":"193cbcd5.135b83","name":"","func":"var userinput = \"JsonDataset__DataCycleModuleDataset.measureDataset.supplyVoltage\";\n\nmsg.payload = msg.payload[\"JsonDataset__DataCycleModuleDataset.measureDataset.supplyVoltage\"];\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":220,"y":720,"wires":[["77c84f3f.8f4b3"]]}]

Ah, no, that won't work. You can't have multiple levels in the path variable. You can do msg.payload["a"]["b"] but you can't do msg.payload["a.b"] which is what you want to do (where the string is actually a variable but that doesn't make any difference). I am not sure how to solve that.

Ok, damn. is there any chance to use JSONata? I mean, feed a jsonata searchstring by a message string?

I don't know, but when I said I didn't know how to do it in JS, I meant that someone else surely does. I haven't found it so far but likely someone will interject with the solution.

This technique seems to work

msg.payload = {a: {b: 7}}
const path = "a.b"
msg.payload = eval(`msg.payload.${path}`)
return msg;

Thanks a lot!! Yes it works.

Could you give a short explanation on this?

A JSONata example .

[{"id":"c647637b.689c1","type":"inject","z":"b779de97.b1b46","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"payload.JsonDataset__DataCycleModuleDataset.measureDataset.supplyVoltage","payload":"{\"Timestamp__DataCycleModuleDataset\":\"2021-09-09T06:45:45.580Z\",\"ModuleIndex\":3,\"ModuleOk\":true,\"JsonDataset__DataCycleModuleDataset\":{\"measureDataset\":{\"encodingMask\":1,\"ok\":true,\"supplyVoltage\":5.01016976,\"remark\":null,\"temperatureActual\":22,\"measureData\":[{\"bridgeNr\":1,\"cellOffset\":-3.93310546875,\"cellOffsetOk\":true,\"cellSensitivity\":1.7035264726429749,\"cellSensitivityOk\":true,\"pressures\":[{\"encodingMask\":3,\"nr\":1,\"pressureTarget\":0.5,\"pressureActual\":0.4987254,\"pressureRegister\":19032,\"temperatureRegister\":16144,\"ntcRegister\":0,\"chipTemperatureRegister\":15552,\"diodeRegister\":16148,\"outputValue\":0,\"outputValueNormed\":0,\"outputValueDiff\":0,\"outputValueDiffNormed\":0,\"pressureDataOk\":true,\"pressureActualOk\":true,\"chipTemperatureRegisterOk\":true,\"outputValueNormedOk\":null,\"outputValueDiffNormedOk\":null},{\"encodingMask\":3,\"nr\":1,\"pressureTarget\":1.8,\"pressureActual\":1.797337,\"pressureRegister\":11783,\"temperatureRegister\":16148,\"ntcRegister\":0,\"chipTemperatureRegister\":15556,\"diodeRegister\":16148,\"outputValue\":0,\"outputValueNormed\":0,\"outputValueDiff\":0,\"outputValueDiffNormed\":0,\"pressureDataOk\":true,\"pressureActualOk\":true,\"chipTemperatureRegisterOk\":true,\"outputValueNormedOk\":null,\"outputValueDiffNormedOk\":null}],\"pressuresMeasureOk\":true},{\"bridgeNr\":2,\"cellOffset\":1.71234130859375,\"cellOffsetOk\":true,\"cellSensitivity\":1.6407810500749416,\"cellSensitivityOk\":true,\"pressures\":[{\"encodingMask\":3,\"nr\":2,\"pressureTarget\":0.5,\"pressureActual\":0.4987254,\"pressureRegister\":10773,\"temperatureRegister\":16168,\"ntcRegister\":0,\"chipTemperatureRegister\":15552,\"diodeRegister\":16168,\"outputValue\":0,\"outputValueNormed\":0,\"outputValueDiff\":0,\"outputValueDiffNormed\":0,\"pressureDataOk\":true,\"pressureActualOk\":true,\"chipTemperatureRegisterOk\":true,\"outputValueNormedOk\":null,\"outputValueDiffNormedOk\":null},{\"encodingMask\":3,\"nr\":2,\"pressureTarget\":1.8,\"pressureActual\":1.797337,\"pressureRegister\":17755,\"temperatureRegister\":16168,\"ntcRegister\":0,\"chipTemperatureRegister\":15556,\"diodeRegister\":16168,\"outputValue\":0,\"outputValueNormed\":0,\"outputValueDiff\":0,\"outputValueDiffNormed\":0,\"pressureDataOk\":true,\"pressureActualOk\":true,\"chipTemperatureRegisterOk\":true,\"outputValueNormedOk\":null,\"outputValueDiffNormedOk\":null}],\"pressuresMeasureOk\":true}],\"measureOk\":true,\"supplyVoltageOk\":true},\"dataValidation\":{\"dataChangeId\":637667667711844900,\"dataCRC\":0},\"cycleTime\":25601.914,\"timestampEntry\":\"2021-09-09T06:45:45.5796704Z\",\"index\":3,\"objMessage\":{\"locale\":null,\"text\":null},\"message\":{\"locale\":null,\"text\":null},\"modulPartCycleQuality\":1}}","payloadType":"json","x":170,"y":3520,"wires":[["4248b176.d0b738"]]},{"id":"4248b176.d0b738","type":"change","z":"b779de97.b1b46","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"\t$lookup(**,$split($$.topic,\".\")[-1])\t","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":350,"y":3620,"wires":[["77c84f3f.8f4b3"]]},{"id":"77c84f3f.8f4b3","type":"debug","z":"b779de97.b1b46","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":430,"y":3720,"wires":[]}]

Eval in the javascript example creates a string "msg.payload.JsonDataset__DataCycleModuleDataset.measureDataset.supplyVoltage" Then executes it, that is why it is dangerous as it can be used to execute malious code.

No. Don't use eval. It is fraught with danger.

Use RED.util.getObjectProperty

See similar thread here : Alternatives to eval() - #2 by Steve-Mcl

Oh rats! In the absence of the OP's real data I tested my suggestion with a much simpler dataset and didn't include any dots.

Yes the eval suggestion seems to work, but it is obviously fraught with danger (!).

var userinput = "measureDataset.supplyVoltage";
msg.payload = eval(`msg.payload.JsonDataset__DataCycleModuleDataset.${userinput}`);
return msg;

It's all beyond my javascript pay level.

1 Like

I agree, it was all I could get to work at the time. I didn't know about getObjectProperty. It works well.

msg.payload = {a: {b: 7}}
const path = "a.b"
msg.payload = RED.util.getObjectProperty(msg.payload, path)
return msg;
1 Like