Dynamically sending MQTT Messages from Object Array

I have an array of objects stored in msg.myRecipes[] collected from an SQL query. From this array I am retreiving data to create a topic and a payload to send to the broker. Each row corresponds to a message sent over a specifc topic. Currently I only managed to create code for the first element of the array to send to the broker:

// Creating the action message
msg.payload = msg.myRecipes[0].r_ActionPeripheral + "-" + msg.myRecipes[0].r_Action;

// Creating the action message topic
msg.topic = "bigBoiTeam/default/default/action/" + msg.myRecipes[0].r_TargetMACAddress;
return msg;

My nodes are configure like this:

image

I want to be able to send all the message with their corresponding topic of the array to the broker. I've thought about the problem for awhile but couldn't come up with a solution unfortunately. Any ideas?

Hi @quentinP ,
I don't have much experience with node-red, this meaning could've solution more simple than mine.
Well could you store the sql return in a flow variable and after that, read this variable to send just first item to the broker. After each loop delete the item sent from payload.

I will try reproduce this to share a screenshot.

Maybe use the split node to split up the array and then handle each message.

As @dceejay says split the array then use a change node to assign the topic and payload.
e.g.

[{"id":"fc897e5e.f485a8","type":"inject","z":"5a245aa1.510164","name":"","props":[{"p":"results","v":"[{\"test\":1,\"test2\":\"mac1\"},{\"test\":2,\"test2\":\"mac2\"}]","vt":"json"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":70,"y":2320,"wires":[["c5704e98.b523"]]},{"id":"c5704e98.b523","type":"change","z":"5a245aa1.510164","name":"","rules":[{"t":"move","p":"results","pt":"msg","to":"payload","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":230,"y":2340,"wires":[["e1c153d0.22aec8"]]},{"id":"e1c153d0.22aec8","type":"split","z":"5a245aa1.510164","name":"","splt":"\\n","spltType":"str","arraySplt":1,"arraySpltType":"len","stream":false,"addname":"","x":370,"y":2320,"wires":[["cc69692e.4d81e8"]]},{"id":"cc69692e.4d81e8","type":"change","z":"5a245aa1.510164","name":"","rules":[{"t":"set","p":"topic","pt":"msg","to":"payload.test2","tot":"msg"},{"t":"set","p":"payload","pt":"msg","to":"payload.test","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":530,"y":2320,"wires":[["96985776.50d0c8"]]},{"id":"96985776.50d0c8","type":"debug","z":"5a245aa1.510164","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":530,"y":2220,"wires":[]},{"id":"22536548.e9649a","type":"ui_template","z":"5a245aa1.510164","group":"8b5cde76.edd58","name":"","order":5,"width":0,"height":0,"format":"","storeOutMessages":true,"fwdInMessages":true,"resendOnRefresh":true,"templateScope":"local","x":340,"y":2220,"wires":[["96985776.50d0c8"]]},{"id":"b7a39483.c2f368","type":"template","z":"5a245aa1.510164","name":"","field":"template","fieldType":"msg","format":"handlebars","syntax":"mustache","template":"<iframe width=\"650\" height=\"450\"         src=\"https://embed.windy.com/embed2.html?lat={{payload.lat}}&lon={{payload.lon}}&detailLat=76.206&detailLon=20.566&width=650&height=450&zoom=3&level=surface&overlay=wind&product=ecmwf&menu=&message=&marker=&calendar=now&pressure=&type=map&location=coordinates&detail=&metricWind=default&metricTemp=default&radarRange=-1\"         frameborder=\"0\"></iframe>","output":"str","x":170,"y":2220,"wires":[["22536548.e9649a"]]},{"id":"a6f2d75a.014708","type":"inject","z":"5a245aa1.510164","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"1","topic":"","payload":"{\"lat\":76.206,\"lon\":20.566}","payloadType":"json","x":110,"y":2120,"wires":[["b7a39483.c2f368"]]},{"id":"60f94d0e.b5998c","type":"inject","z":"5a245aa1.510164","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":"1","topic":"","payload":"{\"lat\":76.206,\"lon\":50.566}","payloadType":"json","x":110,"y":2160,"wires":[["b7a39483.c2f368"]]},{"id":"8b5cde76.edd58","type":"ui_group","name":"","tab":"8f03e639.85956","order":1,"disp":true,"width":"6","collapse":false},{"id":"8f03e639.85956","type":"ui_tab","name":"Home","icon":"dashboard","disabled":false,"hidden":false}]

I'm not sure I understand.. Isn't that what I am currently doing through my js code? The problem is that I don't know how long the array will be (i.e. the payload/topic pairs I need to send to my MQTT node)

There is no need for any code you can split the result array with a split node and then use change node to update topic and payload.

You could do it in function node, you would need to loop through array, assign topic and payload, the use node.send(msg) to send each element of array, and at end return null. results.length would give you your array length, or use a forEach loop.

Perfect, the node.send() function is exactly what I needed. Thanks a lot! Here is some example code in case someone has the same question.

// Creating test array
var fruits = ["Banana", "Orange", "Apple", "Mango"];

// Looping through the array to send each message
for (i = 0; i < fruits.length; i++){
    msg.topic = "fruit/" + fruits[i];
    msg.payload = fruits[i];
    node.send(msg)
}

// Not returning the message as the message was returned in the for loop
return null;

You still need to return
use return null; at end of script.

Oops, made in mistake in pasting the code. Fixed it. Thanks!

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