How to handle arrays and manage null indices (Brewfather)

Hi there,

I am trying to get some data from an API (brewfather) and pass that to sensors on home assistant. The API gives a response like this.

The array changes size depending on the number of batches in that state in Brewfather (API)

[{"_id":"bklHukGNhaFUOzWgJ24bDWx9gcz3S4","name":"Batch","batchNo":2,"status":"Completed","brewer":null,"brewDate":1607172885991,"recipe":{"name":"Vienna Lager - 17l"},"fermentationStartDate":1607172885991},{"_id":"15fuw3HnEcKoXOlcGHjn8wtCEaalLW","name":"Batch","batchNo":1,"status":"Completed","brewer":null,"brewDate":1606003200000,"recipe":{"name":"DH - American Pale 17l"},"fermentationStartDate":1606003200000}]

I am trying to pull the name from the batch and pass it to home assistant, using the HA addon.

now this would be all fine, but there is no guarantee there will be 3 elements in the array so i get errors when the array doesn’t have 3 elements.

So I have tried to build a function that iterates through the array, but passes “empty” if that index in the array is empty

I think i have something wrong with my function

var outarr = ["Empty","Empty","Empty"];

for (var i = 0; i < msg.payload.length; i++) {
// var newMsg = {};
// newMsg.payload = msg.payload[i];
 outarr [i] = msg.payload[i];
//node.send(newMsg);
}
return [outarr [1], outarr[2], outarr[3]];

Can anyone point me in the right direction.

Even if the number of objects in array changes, the path of the name wont change. The path can be taken from the debug node. Make function nodes to convert the data in these paths as payload and then use a switch node to check if the data is not null. Pass only such data to next node.

The function must return message object.
In fact sending array of values has special meaning: it sends 3 messages.
However those have to be message objects too.

Anyway, if you want to send array of values out of the function node, you need to create object and assign the expected values to it:

var newmsg = {};
newmsg.payload = [outarr [1], outarr[2], outarr[3]];
return newmsg;

@maxym

I thought this may be the problem.

What i’m actually trying to do is send one message to each of the 3 outputs but i guess i could do

newmsg1.payload = outarr[1]  etc
return [newmsg1, newmsg2, newmsg3]

Are you sure the those array fields are always ordered in the same deterministic order?
I don’t know the logic you wan to achieve, but I suppose you want particular messages ends in dedicated sensors. isn’t it?
If yes, I would split payload to separate messages (doesn’t matter if outputed using one or multiple outputs). Then use switch node to redirect them to dedicated sensors.
Something like this (but I really guessing what you are want to achieve):

BTW to split array into separater messages, you can use split node. You don’t need to write code for that

So i have tried a number of methods that sort of work, so i can directly map the message by path or do a split and switch (this is what i am currently using)

The API represents the beers that I have brewed in various statuses. So in this case it is the completed status. The problem i have is when I drink a batch of beer that element disappears from the message but status of the sensor is still set. So batch x moves to batch x-1 and leaves a duplicate in my sensors if that makes sense

so outcome i am trying to achieve here is that when i remove a batch

@maxym I’ve cracked it, even if it is slightly ugly - but it will do the job

var out1, out2, out3;
var newmsg1, newmsg2, newmsg3;


out1 = "Empty";
out2 = "Empty";
out3 = "Empty";


if (msg.payload.length == 1) {
    out1 = msg.payload[0].recipe.name;
    
} else if (msg.payload.length ==2) {
    out1 = msg.payload[0].recipe.name;
    out2 = msg.payload[1].recipe.name;
    
} else {
    
    out1 = msg.payload [0];    
    out2 = msg.payload [1];
    out3 = msg.payload [2];    
}


newmsg1 = { payload: out1 };
newmsg2 = { payload: out2 };
newmsg3 = { payload: out3 };

return [newmsg1, newmsg2, newmsg3];

stil not sure why you are so confident that value from payload[0] has to land always in the first sensor etc. Couldn’t batchNo1 appear in second array element while batchNo2 in the first element? Couldn’t be first batch missing while the second and the third exist in data?
Even if data you provided I can see BatchNo2 and BatchNo1 in reversed order :slight_smile:

But I’m sure you know your data better than me. Good you make it working.

The order really isn’t important to be fair but it does seem to bring the most recent in the lowest slot. The big issue for me was dealing with the “empty slots”. The idea is only to show what’s in each status.

Thanks for your help.

To your point. The batch numbers are sequential numbers largest is the most recent. They will come and go as beer gets drunk, so in the most general case you may see batch 2,4 and 7, say in the payload