Stuck on objects of objects to object

Hi everyone,
I am getting stuck on creating an object from an object of objects.
Of each msg.payload.vessels I want to grab MMSI, Speed etc, but my function node is not doing what I expected it to do, besides perhaps creating some :man_facepalming: with some of you :joy:.

flows .json (42.3 KB)

any advise is appreciated

First I would say can you sort the inject payload to as is has some oddities (bad names for properties)

Second msg.payload.vessels is not an array, so you may want to use Object.values to make it one.
example

const newMsg = {payload:[]};
const payload = Object.values(msg.payload.vessels);
for (var i = 0; i < payload.length; i++) {
    newMsg.payload[i] = {
        "mmsi": payload[i].mmsi,
        "SOG": payload[i].navigation.speedOverGround
    }
}
msg = newMsg;
return msg;

This only does one of the objects from the object.
It only does the first one, it doesn't loop.

It loops and outputs an array with 16 elements. Please describe exactly the output you require.

Output

[{"mmsi":"246221000","SOG":0},{"mmsi":"244710681","SOG":2.3664450439438554},{"mmsi":"244130293","SOG":2.6236673313290573},{"mmsi":"244010086","SOG":2.675111788806098},{"mmsi":"244770559","SOG":0.7202224046785647},{"mmsi":"244690278","SOG":1.9548893841275328},{"mmsi":"244830937","SOG":3.1895563635765014},{"mmsi":"244002105","SOG":2.1606672140356946},{"mmsi":"370110000","SOG":3.6011120233928238},{"mmsi":"244368000","SOG":3.704000938346905},{"mmsi":"244077624","SOG":0},{"mmsi":"244020081","SOG":0.051444457477040344},{"mmsi":"244770433","SOG":1.49188926683417},{"mmsi":"244650640","SOG":2.675111788806098},{"mmsi":"244057950","SOG":0},{"mmsi":"205775000","SOG":2.726556246283138}]

Sorry, my bad. Apologies

I am getting the msg.payload.vessels from a TCP node.

As E1cid mentioned, some have bad properties.
How can I skip or overwrite undefined?

I have tried this, but no luck:

const newMsg = {payload:[]};
const payload = Object.values(msg.payload.vessels);
for (var i = 0; i < payload.length; i++) {
    newMsg.payload[i] = {
        "MMSI": payload[i].mmsi,
        "Name": payload[i].name,
        "SOG": (payload[i].navigation.speedOverGround.value===undefined ? payload[i].navigation.speedOverGround.value: 0),
        "COG": (payload[i].navigation.courseOverGroundTrue.value===undefined ? payload[i].navigation.courseOverGroundTrue.value: 0)
    }
}
msg = newMsg;
return msg;

I don't mind writing 0 or skipping an item.
image

The error you get is that navigation.courseOverGroundTrue doe not exist so when you try to look for value it throws an error as the prior property does not exist. So your check should be on the prior property or may be multiple conditionals.

const newMsg = {payload:[]};
const payload = Object.values(msg.payload.vessels);
for (var i = 0; i < payload.length; i++) {
    newMsg.payload[i] = {
        "MMSI": payload[i].mmsi,
        "Name": payload[i].name,
        "SOG": (payload[i].navigation.speedOverGround ? payload[i].navigation.speedOverGround.value : 0),
        "COG": (payload[i].navigation.courseOverGroundTrue ? payload[i].navigation.courseOverGroundTrue.value : 0)
    }
}
msg = newMsg;
return msg;
1 Like

Turns out that sometimes not only a navigation.speedOverGround or navigation.courseOverGround is missing, but the whole .navigation is missing.

image

I have try to bypass that one that has the missing .navigation with:

const newMsg = {payload:[]};
const payload = Object.values(msg.payload.vessels);
for (var i = 0; i < payload.length; i++) {
if (newMsg.payload[i] != undefined){
    {if (newMsg.payload[i].navigation != undefined)
    {
    newMsg.payload[i] = {
        "MMSI": payload[i].mmsi,
        "Name": payload[i].name,
        "SOG": (payload[i].navigation.speedOverGround ? payload[i].navigation.speedOverGround.value : "--,-"),
        "COG": (payload[i].navigation.courseOverGroundTrue ? payload[i].navigation.courseOverGroundTrue.value : "--,-"),
        "HDG": (payload[i].navigation.headingTrue ? payload[i].navigation.headingTrue.value : "--,-"),
        "Longitude": (payload[i].navigation.position.value ? payload[i].navigation.position.value.longitude : "Undefined"),
        "Latitude": (payload[i].navigation.position.value ? payload[i].navigation.position.value.latitude : "Undefined"),
        "Status": (payload[i].navigation.state ? payload[i].navigation.state.value : "Undefined"),
        "Destination": (payload[i].navigation.destination ? payload[i].navigation.destination.commonName.value : "Undefined"),
        "VHF": (payload[i].communication ? payload[i].communication.callsignVhf : "Undefined")
    } 
}
}
}
}
msg = newMsg;
return msg;

But that gives me:

image

The injectnode is a copy of the object I receive. The second from last MMSI is giving me the headache.

flows.json (344.7 KB)

I have not imported your latest, as the inject object is just to large, you would do better removing most vessels and making it more manageable

Possible example

const newMsg = {payload:[]};
const payload = Object.values(msg.payload.vessels);
for (var i = 0; i < payload.length; i++) {
    newMsg.payload[i] = {};
    newMsg.payload[i].MMSI = payload[i].mmsi;
    newMsg.payload[i].Name = payload[i].name;
    if (payload[i].navigation){
        newMsg.payload[i].SOG = (payload[i].navigation.speedOverGround ? payload[i].navigation.speedOverGround.value : "--,-");
        newMsg.payload[i].COG = (payload[i].navigation.courseOverGroundTrue ? payload[i].navigation.courseOverGroundTrue.value : "--,-");
        newMsg.payload[i].HDG = (payload[i].navigation.headingTrue ? payload[i].navigation.headingTrue.value : "--,-");
    }
    if(payload[i].communication){
        newMsg.payload[i].VHF = (payload[i].communication ? payload[i].communication.callsignVhf : "Undefined");
    } 
}
msg = newMsg;
return msg;

I did say you might require multiple conditionals.

1 Like

Thanks @E1cid, I'm learning a lot here.

After lots of trying, I got this to work just now;

const newMsg = {payload:[]};
const payload = Object.values(msg.payload.vessels);
for (var i = 0; i < payload.length; i++) {
   if (payload[i].hasOwnProperty("navigation")){
       
    newMsg.payload[i] = {
        "MMSI": payload[i].mmsi,
        "Name": payload[i].name,
        "SOG": (payload[i].navigation.speedOverGround ? payload[i].navigation.speedOverGround.value : "--,-"),
        "COG": (payload[i].navigation.courseOverGroundTrue ? payload[i].navigation.courseOverGroundTrue.value : "--,-"),
        "HDG": (payload[i].navigation.headingTrue ? payload[i].navigation.headingTrue.value : "--,-"),
        "Longitude": (payload[i].navigation.position.value ? payload[i].navigation.position.value.longitude : "Undefined"),
        "Latitude": (payload[i].navigation.position.value ? payload[i].navigation.position.value.latitude : "Undefined"),
        "Status": (payload[i].navigation.state ? payload[i].navigation.state.value : "Undefined"),
        "Destination": (payload[i].navigation.destination ? payload[i].navigation.destination.commonName.value : "Undefined"),
        "VHF": (payload[i].communication ? payload[i].communication.callsignVhf : "Undefined")
    } 
}
}
msg = newMsg;
return msg;

This way I skip the whole object.

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