Thursday, June 7, 2018

Working with messages - part 2

Let's say we want to perform a transformation that is the opposite of the one shown in the previous post. 

In such case the input msg.payload is :


[{"name1":1},{"name2":2},{"name3":3}]

and we want the following array as the outcome:

[{"Name":"name1","Number":1},{"Name":"name2","Number":2},{"Name":"name3","Number":3}]

I have to say that the solution is not trivial but at the end of the day the final code will be very concise thanks to the use of array destructuring.


As usual, we will need to loop over the original array and take each element in separate for an additional processing. The first iteration of the loop will provide us the following object: 


{ name1: 1 }

The thing here is: how we can possibly handle the key given that it will change in each iteration of the loop?

It is not possible to use object destructuring as this would require knowing the key name in advance. So, this would not work:

let {Name} = {"name1" : 1};
console.log(Name);

The variable Name would get the value undefined.

We have to resort to a special method from JavaScript to extract each the keys and the values from the original array. This is the method Object.entries()

The only problem is that this method will return an array of the keys and values, as shown below:


let payload = [{"name1":1},{"name2":2},{"name3":3}];
for (let elem of payload) {
let a = Object.entries(elem);
console.log(a);



and the following is displayed in the console:


[ [ 'name1', 1 ] ]
[ [ 'name2', 2 ] ]
[ [ 'name3', 3 ] ]

Each loop iteration will return an array and each of these arrays contains another array with the pair [key, value]

Sounds like this is getting complicated, right?  Fortunately, the use of the array destructuring will get us back to the track.

We can extract the key and the value using the array destructuring shown in the left side of the equal sign:

[ [ a,b ] ] = [ [  "name1" , '1 ] ]

which assigns a = "name1" and b = 1


Finally, this is the code to use inside the node function :


let arr = [];

for (let elem of msg.payload) {
let [[a,b]] = Object.entries(elem);
arr.push({"Name": a, "Number": b});
}

msg.payload = arr;
return msg;


and this is what the debug node will display:






Flow:


[{"id":"eb3b9fba.c051d","type":"debug","z":"e57cf4d8.3c8218","name":"Output","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","x":558,"y":512,"wires":[]},{"id":"c656406b.904d6","type":"function","z":"e57cf4d8.3c8218","name":"For of loop","func":"let arr = [];\n\nfor (let elem of msg.payload) {\nlet [[a,b]] = Object.entries(elem);\narr.push({\"Name\": a, \"Number\": b});\n}\n\nmsg.payload = arr;\nreturn msg;","outputs":1,"noerr":0,"x":412.99999237060547,"y":511.99999809265137,"wires":[["eb3b9fba.c051d"]]},{"id":"bafa5144.bec81","type":"inject","z":"e57cf4d8.3c8218","name":"","topic":"","payload":"[{\"name1\":1},{\"name2\":2},{\"name3\":3}]","payloadType":"json","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":240.99999237060547,"y":512,"wires":[["c656406b.904d6"]]}]