6

I need the Accel object as part of the payload object:

  • msg.payload.Accel.x : 1
  • msg.payload.Accel.y : 2
  • msg.payload.Accel.z : 3

How can I add Accel and x,z,y to payload, ideally using the change node?

I tried this already:

msg.payload.Accel['x'] = 1;
return msg;

and got an error:

"TypeError: Cannot set property 'x' of undefined"
jpsstack
  • 1,221
  • 4
  • 18
  • 29

2 Answers2

6

If payload is already an object, you can use a Change node to add or modify properties in payload like this:

enter image description here

[{"id":"a5a26aa9.8e0c48","type":"change","z":"b46a495a.46a938","name":"","rules":[{"t":"set","p":"payload.Accel.x","pt":"msg","to":"1","tot":"num"},{"t":"set","p":"payload.Accel.y","pt":"msg","to":"2","tot":"num"},{"t":"set","p":"payload.Accel.z","pt":"msg","to":"3","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":260,"wires":[["85a0573d.ed8788","e0cc9521.5adb38"]]}]

If payload comes in as a string (or another non-object) and you want to use a Change node to output payload as an object, you first have to use a rule to set msg.payload to an empty JSON object, then further rules to set msg.payload.Accel.x to 1, etc.:

enter image description here

[{"id":"a5a26aa9.8e0c48","type":"change","z":"b46a495a.46a938","name":"","rules":[{"t":"set","p":"payload","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"payload.Accel.x","pt":"msg","to":"1","tot":"num"},{"t":"set","p":"payload.Accel.y","pt":"msg","to":"2","tot":"num"},{"t":"set","p":"payload.Accel.z","pt":"msg","to":"3","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":260,"wires":[["85a0573d.ed8788","e0cc9521.5adb38"]]}]

If payload comes in as a string (or another non-object) and you want to use a Change node to output payload as an object, and additionally preserve the old payload content as a property of the new payload object, then you have to first use a rule to store the original payload in a temp variable before you change payload to an object:

enter image description here

[{"id":"a5a26aa9.8e0c48","type":"change","z":"b46a495a.46a938","name":"","rules":[{"t":"set","p":"temp","pt":"msg","to":"payload","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"{}","tot":"json"},{"t":"set","p":"payload.Accel.x","pt":"msg","to":"1","tot":"num"},{"t":"set","p":"payload.Accel.y","pt":"msg","to":"2","tot":"num"},{"t":"set","p":"payload.Accel.z","pt":"msg","to":"temp","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":270,"y":260,"wires":[["85a0573d.ed8788","e0cc9521.5adb38"]]}]
Jpsy
  • 20,077
  • 7
  • 118
  • 115
  • Setting msg.payload as empty JSON is not needed anymore. My msg.payload arrives as TRUE. Changing it to msg.payload.boolvalue and adding msg.payload.time makes it an object automatically. – S. Gissel Dec 23 '22 at 07:54
5

It all depends on what the msg.payload is to start with. If the input to the function node is a string then msg.payload will be a string and you can't just add arbitrary properties to it.

If the input is already an object then it can be extended, but you need to create the intermediate layers in the object before you can add the value. e.g. assuming the following input msg.payload:

{
  foo: 25,
  bar: 'testing'
}

To add Accel.x you would first need to add a Accel key before trying to add a value to Accel.x. With a function node you would do it like this:

msg.payload.Accel = {};
msg.payload.Accel.x = 1;
msg.payload.Accel['y'] = 2;
return msg;

With a change node it would look something like this as the change node will add the empty layers for you:

Change Node Settings

hardillb
  • 54,545
  • 11
  • 67
  • 105
  • If payload comes in as a string, you can still change it to an object with the Change node. To do so start with a rule of `Set` `msg.`payload to `JSON`{}   then use a second rule to set `msg.`payload.Accel.x etc. – Jpsy Jun 26 '19 at 19:44