Setting JSON structure

Hi All,

image

I am passing a JSON into two function nodes. The function nodes decode my msg.payload.payload_raw, by first changing it to 'Base64' and and then decode.

Decoder 1

let data = msg.payload.payload_raw;
let bytes = new Buffer(data,'Base64');

let decoded = context.Decoder(bytes, msg.payload.port);
msg.payload.uplink_message.decoded_payload = decoded;
return msg;

Decoder 2

let data = msg.payload.payload_raw;
let bytes = new Buffer(data,'Base64');

let decoded = context.Decoder(bytes, msg.payload.port);
msg.payload.decoded_payload = decoded;
return msg;

The only difference is that in Decoder 1 is "msg.payload.uplink_message.decoded_payload = decoded" and in Decoder 2 is "msg.payload.decoded_payload = decoded"

Function node Decoder 1 error

function : (error)

"TypeError: Cannot set property 'decoded_payload' of undefined"

Why is it doing this?

[{"id":"67c0cd0e.e13064","type":"function","z":"1f9de5c0.4c944a","name":"Decoder 1","func":"let data = msg.payload.payload_raw;\nlet bytes = new Buffer(data,'Base64');\n\nlet decoded = context.Decoder(bytes, msg.payload.port);\nmsg.payload.uplink_message.decoded_payload = decoded;\nreturn msg;","outputs":1,"noerr":0,"initialize":"context.Decoder = function(bytes, port) {\n  // Decode an uplink message from a buffer\n  // (array) of bytes to an object of fields.\n  var decoded = {};\n\n  if (port === 1)\n  {\n    decoded.type = \"position\";\n    \n    decoded.latitudeDeg = bytes[0] + bytes[1] * 256 + bytes[2] * 65536 + bytes[3] * 16777216;\n    if (decoded.latitudeDeg >= 0x80000000)\n      decoded.latitudeDeg -= 0x100000000;\n    decoded.latitudeDeg /= 1e7;\n      \n    decoded.longitudeDeg = bytes[4] + bytes[5] * 256 + bytes[6] * 65536 + bytes[7] * 16777216;\n    if (decoded.longitudeDeg >= 0x80000000)\n      decoded.longitudeDeg -= 0x100000000;\n    decoded.longitudeDeg /= 1e7;\n      \n    decoded.inTrip = ((bytes[8] & 0x1) !== 0) ? true : false;\n    decoded.fixFailed = ((bytes[8] & 0x2) !== 0) ? true : false;\n    decoded.headingDeg = (bytes[8] >> 2) * 5.625;\n    \n    decoded.speedKmph = bytes[9];\n    decoded.batV = bytes[10] * 0.025;\n  }\n  else if (port === 2)\n  {\n    decoded.type = \"downlink ack\";\n    \n    decoded.sequence = (bytes[0] & 0x7F);\n    decoded.accepted = ((bytes[0] & 0x80) !== 0) ? true : false;\n    decoded.fwMaj = bytes[1];\n    decoded.fwMin = bytes[2];\n  }\n  else if (port === 3)\n  {\n    decoded.type = \"stats\";\n   \n    decoded.initialBatV    = (((bytes[0] & 0xF) !== 0) ? (4.0 + (bytes[0] & 0xF) * 0.100) : null);\n    decoded.txCount        =  32 * ((bytes[0] >> 4) + (bytes[1]  & 0x7F) *  16);\n    decoded.tripCount      =  32 * ((bytes[1] >> 7) + (bytes[2]  & 0xFF) *   2\n                                                    + (bytes[3]  & 0x0F) * 512);\n    decoded.gpsSuccesses   =  32 * ((bytes[3] >> 4) + (bytes[4]  & 0x3F) *  16);\n    decoded.gpsFails       =  32 * ((bytes[4] >> 6) + (bytes[5]  & 0x3F) *   4);\n    decoded.aveGpsFixS     =   1 * ((bytes[5] >> 6) + (bytes[6]  & 0x7F) *   4);\n    decoded.aveGpsFailS    =   1 * ((bytes[6] >> 7) + (bytes[7]  & 0xFF) *   2);\n    decoded.aveGpsFreshenS =   1 * ((bytes[7] >> 8) + (bytes[8]  & 0xFF) *   1);\n    decoded.wakeupsPerTrip =   1 * ((bytes[8] >> 8) + (bytes[9]  & 0x7F) *   1);\n    decoded.uptimeWeeks    =   1 * ((bytes[9] >> 7) + (bytes[10] & 0xFF) *   2);\n  }\n\n  return decoded;\n}","finalize":"","libs":[],"x":370,"y":200,"wires":[["7aede05c.a9783"]]}]

[admin edit: fixed trailing ticks to backticks]

You have not provided sample data (you only posted the function Decoder1)

Select all the relevant nodes before exporting.

Actually, i dont need to see your full flow.

The error is exactly as it states Cannot set property 'decoded_payload' of undefined"

look at the line ...
msg.payload.uplink_message.decoded_payload = decoded;
... it is highly probable uplink_message is not a property of msg.payload so try this instead...

Decoder 1

let data = msg.payload.payload_raw;
let bytes = new Buffer(data,'Base64');
let decoded = context.Decoder(bytes, msg.payload.port);
msg.payload.uplink_message = { decoded_payload : decoded };
return msg;

PS
let bytes = new Buffer(data,'Base64'); is depreciated
you should use let bytes = Buffer.from( );

[{"id":"1f9de5c0.4c944a","type":"tab","label":"Flow 11","disabled":false,"info":""},{"id":"67c0cd0e.e13064","type":"function","z":"1f9de5c0.4c944a","name":"Decoder 1","func":"let data = msg.payload.payload_raw;\nlet bytes = new Buffer(data,'Base64');\n\nlet decoded = context.Decoder(bytes, msg.payload.port);\nmsg.payload.uplink_message.decoded_payload = decoded;\nreturn msg;","outputs":1,"noerr":0,"initialize":"context.Decoder = function(bytes, port) {\n  // Decode an uplink message from a buffer\n  // (array) of bytes to an object of fields.\n  var decoded = {};\n\n  if (port === 1)\n  {\n    decoded.type = \"position\";\n    \n    decoded.latitudeDeg = bytes[0] + bytes[1] * 256 + bytes[2] * 65536 + bytes[3] * 16777216;\n    if (decoded.latitudeDeg >= 0x80000000)\n      decoded.latitudeDeg -= 0x100000000;\n    decoded.latitudeDeg /= 1e7;\n      \n    decoded.longitudeDeg = bytes[4] + bytes[5] * 256 + bytes[6] * 65536 + bytes[7] * 16777216;\n    if (decoded.longitudeDeg >= 0x80000000)\n      decoded.longitudeDeg -= 0x100000000;\n    decoded.longitudeDeg /= 1e7;\n      \n    decoded.inTrip = ((bytes[8] & 0x1) !== 0) ? true : false;\n    decoded.fixFailed = ((bytes[8] & 0x2) !== 0) ? true : false;\n    decoded.headingDeg = (bytes[8] >> 2) * 5.625;\n    \n    decoded.speedKmph = bytes[9];\n    decoded.batV = bytes[10] * 0.025;\n  }\n  else if (port === 2)\n  {\n    decoded.type = \"downlink ack\";\n    \n    decoded.sequence = (bytes[0] & 0x7F);\n    decoded.accepted = ((bytes[0] & 0x80) !== 0) ? true : false;\n    decoded.fwMaj = bytes[1];\n    decoded.fwMin = bytes[2];\n  }\n  else if (port === 3)\n  {\n    decoded.type = \"stats\";\n   \n    decoded.initialBatV    = (((bytes[0] & 0xF) !== 0) ? (4.0 + (bytes[0] & 0xF) * 0.100) : null);\n    decoded.txCount        =  32 * ((bytes[0] >> 4) + (bytes[1]  & 0x7F) *  16);\n    decoded.tripCount      =  32 * ((bytes[1] >> 7) + (bytes[2]  & 0xFF) *   2\n                                                    + (bytes[3]  & 0x0F) * 512);\n    decoded.gpsSuccesses   =  32 * ((bytes[3] >> 4) + (bytes[4]  & 0x3F) *  16);\n    decoded.gpsFails       =  32 * ((bytes[4] >> 6) + (bytes[5]  & 0x3F) *   4);\n    decoded.aveGpsFixS     =   1 * ((bytes[5] >> 6) + (bytes[6]  & 0x7F) *   4);\n    decoded.aveGpsFailS    =   1 * ((bytes[6] >> 7) + (bytes[7]  & 0xFF) *   2);\n    decoded.aveGpsFreshenS =   1 * ((bytes[7] >> 8) + (bytes[8]  & 0xFF) *   1);\n    decoded.wakeupsPerTrip =   1 * ((bytes[8] >> 8) + (bytes[9]  & 0x7F) *   1);\n    decoded.uptimeWeeks    =   1 * ((bytes[9] >> 7) + (bytes[10] & 0xFF) *   2);\n  }\n\n  return decoded;\n}","finalize":"","libs":[],"x":370,"y":200,"wires":[["7aede05c.a9783"]]},{"id":"333f342c.ef334c","type":"inject","z":"1f9de5c0.4c944a","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"{\"payload_raw\":\"1Ok77vxxVxIUAKE=\",\"port\":1,\"app_id:\":\"ttn_tracker_oyster_123\",\"dev_id\":\"oyster_2\",\"hardware_serial\":\"70B3D57050006F77\",\"counter\":47}","payloadType":"json","x":190,"y":200,"wires":[["67c0cd0e.e13064","60572671.a878e8"]]},{"id":"7aede05c.a9783","type":"debug","z":"1f9de5c0.4c944a","name":"Decoder 1","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":630,"y":200,"wires":[]},{"id":"60572671.a878e8","type":"function","z":"1f9de5c0.4c944a","name":"Decoder 2","func":"let data = msg.payload.payload_raw;\nlet bytes = new Buffer(data,'Base64');\n\nlet decoded = context.Decoder(bytes, msg.payload.port);\nmsg.payload.decoded_payload = decoded;\nreturn msg;","outputs":1,"noerr":0,"initialize":"context.Decoder = function(bytes, port) {\n  // Decode an uplink message from a buffer\n  // (array) of bytes to an object of fields.\n  var decoded = {};\n\n  if (port === 1)\n  {\n    decoded.type = \"position\";\n    \n    decoded.latitudeDeg = bytes[0] + bytes[1] * 256 + bytes[2] * 65536 + bytes[3] * 16777216;\n    if (decoded.latitudeDeg >= 0x80000000)\n      decoded.latitudeDeg -= 0x100000000;\n    decoded.latitudeDeg /= 1e7;\n      \n    decoded.longitudeDeg = bytes[4] + bytes[5] * 256 + bytes[6] * 65536 + bytes[7] * 16777216;\n    if (decoded.longitudeDeg >= 0x80000000)\n      decoded.longitudeDeg -= 0x100000000;\n    decoded.longitudeDeg /= 1e7;\n      \n    decoded.inTrip = ((bytes[8] & 0x1) !== 0) ? true : false;\n    decoded.fixFailed = ((bytes[8] & 0x2) !== 0) ? true : false;\n    decoded.headingDeg = (bytes[8] >> 2) * 5.625;\n    \n    decoded.speedKmph = bytes[9];\n    decoded.batV = bytes[10] * 0.025;\n  }\n  else if (port === 2)\n  {\n    decoded.type = \"downlink ack\";\n    \n    decoded.sequence = (bytes[0] & 0x7F);\n    decoded.accepted = ((bytes[0] & 0x80) !== 0) ? true : false;\n    decoded.fwMaj = bytes[1];\n    decoded.fwMin = bytes[2];\n  }\n  else if (port === 3)\n  {\n    decoded.type = \"stats\";\n   \n    decoded.initialBatV    = (((bytes[0] & 0xF) !== 0) ? (4.0 + (bytes[0] & 0xF) * 0.100) : null);\n    decoded.txCount        =  32 * ((bytes[0] >> 4) + (bytes[1]  & 0x7F) *  16);\n    decoded.tripCount      =  32 * ((bytes[1] >> 7) + (bytes[2]  & 0xFF) *   2\n                                                    + (bytes[3]  & 0x0F) * 512);\n    decoded.gpsSuccesses   =  32 * ((bytes[3] >> 4) + (bytes[4]  & 0x3F) *  16);\n    decoded.gpsFails       =  32 * ((bytes[4] >> 6) + (bytes[5]  & 0x3F) *   4);\n    decoded.aveGpsFixS     =   1 * ((bytes[5] >> 6) + (bytes[6]  & 0x7F) *   4);\n    decoded.aveGpsFailS    =   1 * ((bytes[6] >> 7) + (bytes[7]  & 0xFF) *   2);\n    decoded.aveGpsFreshenS =   1 * ((bytes[7] >> 8) + (bytes[8]  & 0xFF) *   1);\n    decoded.wakeupsPerTrip =   1 * ((bytes[8] >> 8) + (bytes[9]  & 0x7F) *   1);\n    decoded.uptimeWeeks    =   1 * ((bytes[9] >> 7) + (bytes[10] & 0xFF) *   2);\n  }\n\n  return decoded;\n}","finalize":"","libs":[],"x":370,"y":260,"wires":[["7fc1a132.7f07e"]]},{"id":"7fc1a132.7f07e","type":"debug","z":"1f9de5c0.4c944a","name":"Decoder 2","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"true","targetType":"full","statusVal":"payload","statusType":"auto","x":610,"y":260,"wires":[]}]

As I said above, the problem is

Change Decoder 1 to ...

let data = msg.payload.payload_raw;
let bytes = new Buffer(data,'Base64');

let decoded = context.Decoder(bytes, msg.payload.port);
msg.payload.uplink_message = { decoded_payload: decoded };
return msg;

you will get...

image

1 Like

Thank you @Steve-Mcl

So you first need to make uplink_message an property of payload. Then you can add the property decoded_payload to uplink_message.

let bytes = Buffer.from(msg.payload.payload_raw,'Base64');

let decoded = context.Decoder(bytes, msg.payload.port);
msg.payload.uplink_message = { decoded_payload: decoded };
return msg;
1 Like

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