Message formatting from JSON to Object/Array

Warning this isn't going to be pretty, I pretty sure non of my terminology will be correct. Don't think it needs saying but I don't really know what I'm doing.

I'm trying to convert a message from JSON to Object/Array? notation. Thought I got close but in the example linked I'm getting and extra "object/array child".

What I need:
0: > "measurement" : "testDevice"

What I'm getting:
0: > "measurement" : > "payload" : "testDevice"

Think my lack of terminaloly if failing me here, as Google might be more help if I new how to search the problem. :frowning:

Function code:

var msg1 = {payload:msg.payload.device};
var msg2 = {payload:msg.payload.data};

msg.payload = [
    {
        measurement: msg1,
        fields: {
            data: msg2
        }
    }
];
return msg;

Node Example:

[{"id":"f3abc4cf.bf56a8","type":"inject","z":"ec5aafa2.fcafb","name":"JSON String","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"device\":\"testDevice\",\"data\":\"testData\"}","payloadType":"json","x":790,"y":420,"wires":[["d9595840.361e38"]]},{"id":"d9595840.361e38","type":"function","z":"ec5aafa2.fcafb","name":"","func":"var msg1 = {payload:msg.payload.device};\nvar msg2 = {payload:msg.payload.data};\n\nmsg.payload = [\n    {\n        measurement: msg1,\n        fields: {\n            data: msg2\n        }\n    }\n];\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":980,"y":420,"wires":[["23112814.a43278"]]},{"id":"23112814.a43278","type":"debug","z":"ec5aafa2.fcafb","name":"Incorrect","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1160,"y":420,"wires":[]},{"id":"281bada5.7f2602","type":"function","z":"ec5aafa2.fcafb","name":"","func":"msg.payload = [\n    {\n        measurement: \"testDevice\",\n        fields: {\n            data: \"testData\",\n        },\n    }\n];\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":980,"y":380,"wires":[["1289e8ef.e81067"]]},{"id":"4def3a8e.7d8624","type":"inject","z":"ec5aafa2.fcafb","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"","payloadType":"date","x":780,"y":380,"wires":[["281bada5.7f2602"]]},{"id":"1289e8ef.e81067","type":"debug","z":"ec5aafa2.fcafb","name":"Correct","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1160,"y":380,"wires":[]}]
1 Like

I am afraid your notation is a bit awry as you suggest. The output of the lower inject node is not json, it is a javascript object. The string you have entered into the inject node config is json, but you have told it to convert that to a javascript object.

You are nearly there, you are overthinking the problem. All you need it something like

msg.payload = [
    {
        measurement: msg.payload.device,
        fields: {
            data: msg.payload.data
        }
    }
];
return msg;

or if you want to pick up the values to a local variable first then

let measurement = msg.payload.device
let data = msg.payload.data

msg.payload = [
    {
        measurement: measurement,
        fields: {
            data: data
        }
    }
];
return msg;

Have a read of this page from the docs, it should help you to understand messages. Working with messages : Node-RED

1 Like

Just to provide another way to accomplish the same thing: I like using a JSONata expression inside a change node for cases like this. For your sample data, the J: expression would be:

[
    {
        measurement: payload.device,
        fields: {
            data: payload.data
        }
    }
]

JSONata uses a less familiar "lambda" expression syntax, which looks similar to JS -- and so most people prefer to avoid it and use plain javascript. But it provides a rather powerful syntax to transform JS object structures... similar in design to the way XSLT uses XPath to transform XML structures.

FWIW, I think it's a nice tool to have at hand -- and while it's easy to learn, it does take a while to master. If you want to learn more, you can try it out at try.jsonata.org

2 Likes

Thank you guys, just the input I needed.

@Colin, sorry I wasn't very articulate on my requirements. I wanted the JSON inject to output at the debug as a javascript object, to match the example provided on top. I fear I'm just typing in circles now. :rofl: Anyway, thanks again!

@shrickus, thanks, you might have lost me a bit but I'll do some homework.

I think your code is confusing people. If you require just an array containing a object with one key value pair, it would be more like below.

msg.payload = [
    {
    measurement: msg.payload.data
    }
];

Would that not be "Invalid JSONata expression, Key must evaluate to a string" as your keys would need to be in quotes.

Maybe back round would have been a better place to start.

I am taking a callback and sending it to InfluxDB. The callback arrives as a JSON (string/object - please correct me to which one) as in my example of the JSON inject node. As with the example from the InfluxDB batch node (node-red-contrib-influxdb (node) - Node-RED), it needs to be a javascript object.

My understanding of all this is very limited so apologies for the confusion but thank you for the help.

Of course, you are right... too big a hurry.

And now I see he wants a simpler output format anyway.

Feed it into a debug node and if it says it is a string it is a string. If it is in JSON format then it is a JSON string, also known as a JSON object. If the debug node shows it as an object then it is a javascript object.

Whichever it is, show us what it looks like so we can understand what you are starting with.

Looks like you are looking for JSON.parse(string) with string is a json-structure.
I have no access to my node-red instance right now to test your code.

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