Help with pushing objects to array

hi all,
I do have an unexpected result from that code.

var topic = msg.topic;
var deviceName = topic.split("/")[1];
var deviceTopic = topic.split("/")[2];
var deviceList = global.get('mitiiot_devices')||[]; //array

//node.warn(deviceList.length);

if(deviceTopic == "STATE")
{
    if(isInArray(deviceList, deviceName))
    {
        //node.warn(deviceName + " exists already");    
    }
    else
    {
        //node.warn(deviceName + " not existing");  
        var ssid = msg.payload.Wifi.SSId;
        var bssid = msg.payload.Wifi.BSSId;
        tempObj = 
            {
                name: deviceName,
                ip:"192.168.188.0",
                ssid : ssid,
                bssid : bssid
            };
        deviceList.push(tempObj);
    }
}

function isInArray(arr, key)
{
    for(var j=0; j<arr.size; j++)
    {
        tmpObj = arr[j];
        if(tmpOj.name == key)
            return true;
        else
            return false;
    }
}

result is this
Bildschirmfoto 2021-01-26 um 14.25.44

there is a second array wrapping the objects I add. I wanted to push the objects directly to the first array, but it results in array --> array --> object. I cannot see why.

The global array is initialized via config node --> JSON []

:slight_smile: mirco

The "add object" part seems correct. Nothing I can say about the isInArray check, cos you haven't shared it.
But I think, that you have changed that function but those entries are stored before that change so they can be wrong.
Delete that array from global context and start over. Then see if new array is created correctly.

I added that function to the code you see above. It cannot be relevant cause it just reads from it but btw it also fails since I did not expect the second array hierarchy. I purged the array already and started from scratch which ends up exactly like I posted.

To think out loud: deviceList gets a reference to the global array. In this array I simply push an object which means that the array will be extended by one. tempObj is an object with four attributes. It seems that pushing tempObj to the global array does add an array as main data structure.

As we cannot see where you store xxx in global - it could be that you are adding items to sub-array.

This works...

let topic = msg.topic;
let deviceName = topic.split("/")[1];
let deviceTopic = topic.split("/")[2];
let deviceList = global.get('mitiiot_devices') || []; //array

if(deviceTopic == "STATE")
{
    if(isInArray(deviceList, deviceName)) {
        //node.warn(deviceName + " exists already");    
    } else {
        //node.warn(deviceName + " not existing");  
        let tempObj = {
            name: deviceName,
            ip:"192.168.188.0",
            ssid : msg.payload.Wifi.SSId,
            bssid : msg.payload.Wifi.BSSId
        };
        deviceList.push(tempObj);
    }
}

global.set('mitiiot_devices', deviceList); //update global store

function isInArray(arr, key)
{
    for(var j=0; j<arr.length; j++) {
        if(arr[j].name == key) return true;
    }
    return false;
}
return msg;

Issues: not declaring tempObj is likely using the same instance in your sub function, arr.size is not valid (its arr.length), you should use let in loops

thank you for improving my code, highly appreciated. What do you mean with "where" I store my global? I simply use a config node like this:

Expanding on the above suggestions .. you could try the following in on line and discard the isInArray function. It returns true if some element of deviceList already has that deviceName in

if (deviceList.some(el => el.name == deviceName))

Array.some()

1 Like

well, it partly works. Seems as there is happing both now, adding arrays and objects.

Bildschirmfoto 2021-01-26 um 15.55.11

but there is no other function working on this global array. Updating the array display on the context tab show me that already addd objects are being replaced by an array. There is one difference... _msgid. Whenver it is an array, that msgid is being stored as well. It's not part of the code.

found the problem, but did not understand (yet). That is my complete flow...
Bildschirmfoto 2021-01-26 um 16.21.04
the trigger is being fired every 30 secs updating a view component from the current content of that global array. as a left over from playing around the function being not wired in that screenshot was previously wired doing only this:

return global.get('mitiiot_devices');

That is, why ever, throwing the whole array in apparently interacting with the function being connected to the mqtt receiver. I guess it has something to do with the flow context, I will have to read more about those digging through the documentation...

thank you all, I learned much here :slight_smile:

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