How to test for undefined in function node

I have a number of messages which share the same topic but with various payload objects, which vary from message to message.

The code bellow does what I need when the relevant object is present in the message

var1 = {payload: msg.payload.S29cmnd_D15.STATE};
return var1;

I would like to know how to avoid getting this error "TypeError: Cannot read property 'STATE' of undefined" if that object is not in the message.

Basically I think I need to "test" if the object is there before trying to assign it, but cannot figure out the correct code.

Many Thanks...

A much used method I've seen used a lot is to use this type of construct

var1 = something || 0;

Then if something doesn't exist - var1 will be assigned 0

Hi @smcgann99

You can check if it exists using something like:

if (msg.payload.hasOwnProperty("S29cmnd_D15")) {
   msg.payload = msg.payload.S29cmnd_D15.STATE;
   return msg;
} else {
  // do something else because it does not exist
}

Note how this code updates and returns the existing msg object, rather than create a new message object - that's generally the best practise to follow.

3 Likes

Many thanks, looks simple once you know how, keep up the good work

Searching google for methods in JavaScript to do this will show you many ways and the pro/cons of each.

the hasOwnProperty works, however, last time i searched the safest/"better" method is to do.

if(typeof msg.payload.S29cmnd_D15 !== 'undefined') {
    // blah blah
} else {
    // more blah
}

If you just want to switch the payload to some element buried in a JS Object (or maybe not!), it's probably easiest/safest to use the JSONata expression shown below:

image

The JSONata expression parser stops as soon as it hits an undefined element in the "path", since any elements after that point are going to be undefined as well.

Taking this message

object
topic: "stat/alarm/RESULT"
payload: object
Time: "2019-12-19T17:09:21"
MCP230XX_INT: object
D0: 1
MS: 2075

I tried the following but this doesn't seem to work any ideas please ?

if (msg.payload.hasOwnProperty("MCP230XX_INT.D0")) {
msg.payload = msg.payload.MCP230XX_INT.D0
msg.topic = "0"
}

return msg;

Maybe its needs

if (msg.payload.hasOwnProperty("MCP230XX_INT")) {
   if (msg.payload.MCP230XX_INT.hasOwnProperty("D0")) {
       msg.payload = msg.payload.MCP230XX_INT.D0
       msg.topic = "0"
   }
}
1 Like

That did the trick thanks a lot :wink:

knolleary Thank you for the solution.

I investigated whether it was possible to use a JSONata expression and found $exits().

So a function node with

if (msg.hasOwnProperty("motor"))
{
    return msg;
}   

is similar to a switch node with JSONata expression set to

$exists(msg.motor)

Now,

  • Wouldn't be nice to get an additional option on the switch node with exists on the drop-down menu and the name of the field on the property?

With the Switch node you can use the is not null option that is already there:

That works for top level properties.

Since NR 1.0 there is also the has key option that can be used to check if a key exists on an object property - but can't be used on the top level object itself.

1 Like

Thank you! So we have 4 different solutions now :slight_smile:

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