Monday, December 25, 2017

CHANGE node - Part 1 - Introduction

The Change node from Node-RED is one of the most useful nodes.

Its purpose is to change the structure (properties and values) of the msg object, so it allows to add, change, move or delete properties (values from the key/value pairs).

A single node allows you to configure several rules in the same configuration dialog tab. The rules can mix the four different kinds of property operations. Each and every rule will be verified in the sequence they have been created.






The Change node has a couple of powerful functionalities: regular expressions when used along with the change rule and JSONata expressions, only for the set rule. JSONata is so powerful that it would deserve a dedicated node (in my opinion). JSONata allows you to manipulate any part of a JSON data structure, including the keys from the key/values pairs (which is not possible in another way by the change node, at least to the best of my knowledge).



Sometimes you may want to get some JSON data, change it to be a JavaScript object and manipulate this data with Node-RED. The JSON data may come from many different sources, like:


1- A  JSON string hard-coded in a Node-RED inject node.

2- An input MQTT node receiving a JSON string from an MQTT broker (as long as the topic configures the JSON string).

3- A Node-RED HTTP request node used to access web services (APIs). Depending on the API the JSON received can be very large and complex.

4- A Node-RED  DWEET node.

5- A database with stored JSON data.


When the input is a standard JSON data you will need to use a Node-RED JSON node to convert the JSON data structure to a JavaScript object.





Notice that injecting a JSON structure (JSON string) inside a Node-RED flow can easily be done with the inject node.




For the purpose of this post, let's craft a JSON string that is simple but has enough elements for testing the node.


By hosting this JSON string inside an inject node we will have an msg object with :

ms.topic
msg.payload



The JSON string will be the value of msg.payload and this msg.payload will have four objects inside:

msg.payload.msg1
msg.payload.msg2
msg.payload.msg3
msg.payload.msg4

The parameter of msg.payload.msg3 will be an array with 4 string.

The parameter of msg.payload.msg4 will be an array of arrays.

I order to keep the testing as simple as possible I will abbreviate the name of the persons with the first letter only (eg. f instead of Frederic).

This is the JSON string I will be using for testing the Change node. When it is hard-coded in a Node-RED inject node it will be used as the payload of the msg object.



{
"msg1": {
"father": "f",
"mother": "m"
},
"msg2": {
"brother": "b",
"sister": "s"
},
"msg3": {
"grands": ["g", "h", "i", "j"]
},
"msg4": {
"ancestors": [
["w1", "w2"],
["x1", "x2"],
["y1", "y2"],
["z1", "z2"]
]
}
}




Alternatively, it could be defined inside a function node by using the statement var msg = {JSON string here};







Flow:


[{"id":"f95ef9d9.55c618","type":"inject","z":"245b0549.fd469a","name":"","topic":"","payload":"{\"msg1\":{\"father\":\"f\",\"mother\":\"m\"},\"msg2\":{\"brother\":\"b\",\"sister\":\"s\"},\"msg3\":{\"grands\":[\"g\",\"h\",\"i\",\"j\"]},\"msg4\":{\"ancestors\":[[\"w1\",\"w2\"],[\"x1\",\"x2\"],[\"y1\",\"y2\"],[\"z1\",\"z2\"]]}}","payloadType":"json","repeat":"","crontab":"","once":false,"x":90,"y":60,"wires":[["5af687da.cf8098"]]},{"id":"dd34d677.51a918","type":"debug","z":"245b0549.fd469a","name":"","active":true,"console":"false","complete":"true","x":430,"y":60,"wires":[]},{"id":"5af687da.cf8098","type":"change","z":"245b0549.fd469a","name":"","rules":[{"t":"set","p":"","pt":"msg","to":"","tot":"msg"},{"t":"change","p":"","pt":"msg","from":"","fromt":"str","to":"","tot":"str"},{"t":"delete","p":"","pt":"msg"},{"t":"move","p":"","pt":"msg","to":"","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":260,"y":60,"wires":[["dd34d677.51a918"]]}]