Dynamic number of returns in function

Hello, I'm trying to have a dynamic number of returns depending on a variable, I did this but it's only handling up to length 6, and sometimes there's up to 20. I'd like to know a proper way to do it !
Thanks

/////////////////////////// Send DATA ///////////////////////////

if      (msg.payload.hotspots.length == 2) return [[hotspotInfluxDB(0), msgInfluxDB(0), hotspotInfluxDB(1), msgInfluxDB(1)], msgTelegram]
else if (msg.payload.hotspots.length == 3) return [[hotspotInfluxDB(0), msgInfluxDB(0), hotspotInfluxDB(1), msgInfluxDB(1), hotspotInfluxDB(2), msgInfluxDB(2)], msgTelegram]
else if (msg.payload.hotspots.length == 4) return [[hotspotInfluxDB(0), msgInfluxDB(0), hotspotInfluxDB(1), msgInfluxDB(1), hotspotInfluxDB(2), msgInfluxDB(2), hotspotInfluxDB(3), msgInfluxDB(3)], msgTelegram]
else if (msg.payload.hotspots.length == 5) return [[hotspotInfluxDB(0), msgInfluxDB(0), hotspotInfluxDB(1), msgInfluxDB(1), hotspotInfluxDB(2), msgInfluxDB(2), hotspotInfluxDB(3), msgInfluxDB(3), hotspotInfluxDB(4), msgInfluxDB(4)], msgTelegram]
else if (msg.payload.hotspots.length == 6) return [[hotspotInfluxDB(0), msgInfluxDB(0), hotspotInfluxDB(1), msgInfluxDB(1), hotspotInfluxDB(2), msgInfluxDB(2), hotspotInfluxDB(3), msgInfluxDB(3), hotspotInfluxDB(4), msgInfluxDB(4), hotspotInfluxDB(5), msgInfluxDB(5)], msgTelegram]
else return [[hotspotInfluxDB(0), msgInfluxDB(0)], msgTelegram]

You need to loop the list of hotspots array and generate a msg array then send that...

Example function code...

const msgTelegram = {payload: "test"};
const msgArray = [];
for (let index = 0; index < msg.payload.hotspots.length; index++) {
    const hotspot = msg.payload.hotspots[index];
    let m = {
        topic: "hotspot/" + (index+1),
        payload: hotspot
    }
    msgArray.push(m)
}
return [msgArray, msgTelegram];

↑ NOTE: It is not clear from your code what is required in the message. I simply put the content of hotspot in the msg.payload & set the topic to something arbitrary.


Demo flow...

[{"id":"75f941daf629c2ba","type":"inject","z":"219b0be6.926804","name":"5","props":[{"p":"msg.payload.hotspots","v":"[\"a\",\"b\",\"c\",\"d\",\"e\"]","vt":"json"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1560,"y":320,"wires":[["bcc8bbbf106ec10f"]]},{"id":"bcc8bbbf106ec10f","type":"function","z":"219b0be6.926804","name":"dyn msg","func":"\nconst msgTelegram = {payload: \"test\"};\nconst msgArray = [];\nfor (let index = 0; index < msg.payload.hotspots.length; index++) {\n    const hotspot = msg.payload.hotspots[index];\n    let m = {\n        topic: \"hotspot/\" + (index+1),\n        payload: hotspot\n    }\n    msgArray.push(m)\n}\nreturn [msgArray, msgTelegram]\n\n","outputs":2,"noerr":0,"initialize":"","finalize":"","libs":[],"x":1720,"y":320,"wires":[["fc3d23dad0eccca5"],[]]},{"id":"fc3d23dad0eccca5","type":"debug","z":"219b0be6.926804","name":"","active":true,"tosidebar":true,"console":false,"tostatus":true,"complete":"payload","targetType":"msg","statusVal":"payload","statusType":"auto","x":1750,"y":360,"wires":[]},{"id":"8520352e4bf4222a","type":"inject","z":"219b0be6.926804","name":"3","props":[{"p":"msg.payload.hotspots","v":"[\"a\",\"b\",\"c\"]","vt":"json"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1550,"y":280,"wires":[["bcc8bbbf106ec10f"]]},{"id":"b3a602887632bcb1","type":"inject","z":"219b0be6.926804","name":"26","props":[{"p":"msg.payload.hotspots","v":"[\"a\",\"b\",\"c\",\"d\",\"e\",\"f\",\"g\",\"h\",\"i\",\"j\",\"k\",\"l\",\"m\",\"n\",\"o\",\"p\",\"q\",\"r\",\"s\",\"t\",\"u\",\"v\",\"x\",\"w\",\"x\",\"y\",\"z\"]","vt":"json"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","x":1550,"y":360,"wires":[["bcc8bbbf106ec10f"]]}]

↑ NOTE: You didnt post the other relevant parts (like hotspotInfluxDB() and msgInfluxDB() etc so the above is a working demo using an array of strings for the hotspot array

@Steve-Mcl beat me too it while I was typing up an example.

you could also use for each. Array.prototype.forEach() - JavaScript | MDN

var arrayTelegram = [];
var array = msg.payload.hotspots;
var arrayLength = msg.payload.hotspots.length;

if (arrayLength > 1) {
    arr.forEach((element, index) => {
        arrayTelegram.push(hotspotInfluxDB(index), msgInfluxDB(index));
    });
}

msg.telegram = arrayTelegram;
return msg;

as steve pointed out. we need more information of the data your trying to manipulate.

Thank you both for the quick replies
Here is the whole code :

/////////////////////////// HASH NAME /////////////////////////// 

String.prototype.hashCode = function() {
  var hash = 0, i, chr;
  if (this.length === 0) return hash;
  for (i = 0; i < this.length; i++) {
    chr   = this.charCodeAt(i);
    hash  = ((hash << 5) - hash) + chr;
    hash |= 0; // Convert to 32bit integer
  }
  return hash;
};

/////////////////////////// CALC DIST /////////////////////////// 

function calcDist(lat1, lon1, lat2, lon2) {
  var p = 0.017453292519943295;    // Math.PI / 180
  var c = Math.cos;
  var a = 0.5 - c((lat2 - lat1) * p)/2 + 
          c(lat1 * p) * c(lat2 * p) * 
          (1 - c((lon2 - lon1) * p))/2;
  return 12742 * Math.asin(Math.sqrt(a)); // 2 * R; R = 6371 km
}

/////////////////////////// TELEGRAM /////////////////////////// 

function hotspotT(NUM) {

dist = calcDist(msg.payload.hotspots[NUM].lat, msg.payload.hotspots[NUM].long, msg.payload.decoded.payload.latitude, msg.payload.decoded.payload.longitude)

if (dist < 1) dist = (dist*1000).toFixed(0) +"m"
else if (dist >= 10) dist = Number(dist).toFixed(1) +"km"
else dist = Number(dist).toFixed(2) +"km"

signal = (msg.payload.hotspots[NUM].rssi + msg.payload.hotspots[NUM].snr).toFixed(0)

messageT = dist +" "+ signal

if (NUM == 0) { messageT = messageT  +" "+ 
//msg.payload.hotspots[NUM].spreading.replace('BW125', '') +" "+
msg.payload.decoded.payload.battery.toFixed(2) +"V "+
Number(msg.payload.decoded.payload.speed) +"km/h\n" }

else messageT = messageT+"\n"

return messageT
}

messageTelegram = hotspotT(0)

let nT = 1
while (nT < msg.payload.hotspots.length) {
    messageTelegram = messageTelegram + hotspotT(nT)
    nT++
}

msgTelegram = { payload : { chatId : -1001589123035, type : "message", content : messageTelegram } }


/////////////////////////// InfluxDB /////////////////////////// 

function msgInfluxDB(NUM) {
messageDB = { payload : {
    distance: calcDist(msg.payload.hotspots[NUM].lat, msg.payload.hotspots[NUM].long, msg.payload.decoded.payload.latitude, msg.payload.decoded.payload.longitude),
    latitude: msg.payload.decoded.payload.latitude,
    longitude: msg.payload.decoded.payload.longitude,
    altitude: msg.payload.decoded.payload.altitude,
	speed: parseFloat(msg.payload.decoded.payload.speed),
    battery: parseFloat(msg.payload.decoded.payload.battery.toFixed(2)),
	sf: parseFloat(msg.payload.hotspots[NUM].spreading.replace('BW125', '').replace('SF', '')),
	rssi: msg.payload.hotspots[NUM].rssi,
	snr: parseFloat(msg.payload.hotspots[NUM].snr.toFixed(1)),
	signal: parseFloat((msg.payload.hotspots[NUM].rssi + msg.payload.hotspots[NUM].snr).toFixed(0)),
	time: (msg.payload.reported_at+(NUM*0.001))*1000000,
	hotspot: msg.payload.hotspots[NUM].name,
    fcnt: msg.payload.fcnt,
    frequency: msg.payload.hotspots[NUM].frequency,
    channel: msg.payload.hotspots[NUM].channel
}}
return messageDB
}

function hotspotInfluxDB(NUM) {
hotspotDB = { payload : {
    latitude: msg.payload.hotspots[NUM].lat,
    longitude: msg.payload.hotspots[NUM].long,
	signal: 100,
	time: 1600000000000000000 + msg.payload.hotspots[NUM].name.hashCode(),
	hotspot: msg.payload.hotspots[NUM].name
}}
return hotspotDB
}


/////////////////////////// Send DATA ///////////////////////////

if      (msg.payload.hotspots.length == 2) return [[hotspotInfluxDB(0), msgInfluxDB(0), hotspotInfluxDB(1), msgInfluxDB(1)], msgTelegram]
else if (msg.payload.hotspots.length == 3) return [[hotspotInfluxDB(0), msgInfluxDB(0), hotspotInfluxDB(1), msgInfluxDB(1), hotspotInfluxDB(2), msgInfluxDB(2)], msgTelegram]
else if (msg.payload.hotspots.length == 4) return [[hotspotInfluxDB(0), msgInfluxDB(0), hotspotInfluxDB(1), msgInfluxDB(1), hotspotInfluxDB(2), msgInfluxDB(2), hotspotInfluxDB(3), msgInfluxDB(3)], msgTelegram]
else if (msg.payload.hotspots.length == 5) return [[hotspotInfluxDB(0), msgInfluxDB(0), hotspotInfluxDB(1), msgInfluxDB(1), hotspotInfluxDB(2), msgInfluxDB(2), hotspotInfluxDB(3), msgInfluxDB(3), hotspotInfluxDB(4), msgInfluxDB(4)], msgTelegram]
else if (msg.payload.hotspots.length == 6) return [[hotspotInfluxDB(0), msgInfluxDB(0), hotspotInfluxDB(1), msgInfluxDB(1), hotspotInfluxDB(2), msgInfluxDB(2), hotspotInfluxDB(3), msgInfluxDB(3), hotspotInfluxDB(4), msgInfluxDB(4), hotspotInfluxDB(5), msgInfluxDB(5)], msgTelegram]
else return [[hotspotInfluxDB(0), msgInfluxDB(0)], msgTelegram]

As you can see telegram and InfluxDB are two different things here
This is made for lorawan coverage mapping with a grafana integration

I have no ansver related to the issue but seeing numbers like this
1600000000000000000 + msg.payload.something is dangerously big for Javascript.

1 Like
/////////////////////////// Send DATA ///////////////////////////
var InfluxArray = [];
msg.payload.hotspots.forEach((element, index) => {
  InfluxArray.push(hotspotInfluxDB(index), msgInfluxDB(index));
})

return [InfluxArray, msgTelegram]

That did the trick ! Thanks for the help

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