Correct format for extracting name of an object nested within an object using Function Node

Hi, I should know the answer to this but I'm get confused when trying to extract a specific piece of data from a JSON line that has an object containing the data I require nested within an object.

To be specific, I have a stream of Zigbee data from different devices coming from my MQTT server. I need to check the second objects name to identify I am reading the correct sensor before parsing the data for onward proccesing.

I can read the data from my chosen device with

msg.payload = {payload: msg.payload.ZbReceived.InnerHallLights.Power}

where Power is the data value I want to extract but that gives an error message when a message from the MQTT server arrives that is something other than the object "InnerHallLight".

I want to identify that second object (the first is ZbReceived) and filter anything that does not mention InnerHallLight.

I have tried reading up on Objects but can't find anything that specifly mentions how to extract the name of an object. Hope this makes sense.

You have not given any example of the complete object, so at a guess
try

msg.payload = msg.payload.ZbReceived[Object.keys(msg.payload.ZbReceived)[0]].Power
return msg;

You can use "Object.getOwnPropertyNames()" to get a list of the object properties, then search for the required inner property

The node red way would be to insert a Switch node that only passes messages where msg.payload.ZbReceived.InnerHallLights is present. You should be able to achieve that using the Has Key option in the Switch node.

image

Any messages containing that will get passed through and others will be blocked.

I note that you are confused as to whether it is Light or Lights so you need to get that right.

If you want to do it in code then

if (msg.payload.ZbReceived.InnerHallLights) {
  // InnerHallLights object is present
} else {
  // not present
}

Thaks Colin, both ideas worked well. I have not used "has key" before. Its new to me so something new learnt.

I had tried to gues at something simlilar to the coded option using

if (msg.object === "InnerHallLights") {

} else {

}

But obviously that did not work.

Appreciate your help. Spent several hours on that last night. This forum and all that help on it are awsome.

Thanks for your help. Appreciate the reply.

The reason that
if (msg.payload.ZbReceived.InnerHallLights) {
works is that if msg.payload.ZbReceived.InnerHallLights does not exist then it will be undefined and an undefined value is considered false when it is tested, whereas an object is considered to be true. You have to be careful using such shortcuts because if msg.payload.ZbReceived.InnerHallLights were a number with value 0 then it would also be considered false. Since you know it is either not present or is an object then the test should be safe.

The more explicit way to test it would be
if (typeof msg.payload.ZbReceived.InnerHallLights != "undefined") {

Thanks for the explanation, I can solve most things but javascript is not a strength of mine and at 72 I struggle with trying to learn it but every little bit of help adds to my knowledge.

I originaly learnt to program using assember on Z80 and 6502 processors back in the 70s.

I love Node Red and it has allowed me to get back into programming with fairly complex home and heating automation projects. It is largely due to the forums and the community spirit that I have been able to ask for help when I get out of my depth. Now I need to figure out what "Has Key" does :slight_smile:

1 Like

The keys are the names of the properties of an object. So if msg.payload.ZbReceived is an object that contains a property InnerHallLights then Has Key will pass.

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