How "bypass" TypeError: Cannot read property '0' of undefined

Dear Sir,
I have a flow that receive some DHT22 values from different NodeMCU via MQTT.

  1. I have created a "JOIN NODE" to JOIN all the sensor values, and make a correct unique long array to send to:

  2. a "FUNCTION NODE" that prepare the GSHEET unique long array with all the DHT sensors.
    The array is make to take the incoming array from the "JoinNode":

GSHEETuniqueLongArray= [
msg.payload.DHTSala[1].payload,  etc etc....
return [GSHEETuniqueLongArray ];

The problem is that if one or more NodeMCU is powered OFF, the "function Node", to make a gsheet array, gives me the error:

"TypeError: Cannot read property '0' of undefined"

Is it possible to tell to this function node to don't consider for example the:
"msg.payload.DHTSala[0].payload" if this nodeMCU is disconnected?

I have already try with:

var a = msg.payload.DHTSala[0].payload;
if (typeof a !== 'undefined') { a = a } else { a="nd"};

but doesn't work!

the problem is that you're looking for a property of something that doesn't exist. So, check the variable type before checking the value of any of it's properties.

let a = msg.payload;
if (a) {
  // check some property
} else {
  // don't check property, do something else

That means that it is the thing that you are trying to fetch element 0 of that is undefined, which looking at your code appears to be msg.payload.DHTEsterno. So something like

if (typeof msg.payload.DHTEsterno === "undefined") {
  // do the undefined thing
} else {
  // do the normal thing

Dear Sir, thanks for the reply.
I'm receiving yet "TypeError: Cannot read property '0' of undefined"

I just tested yours and other solutions, but the pont is that the "msg.payload.DHTEsterno" IS COMPLETELY NOT present, because the MQTT data/array from the "DHTEsterno" is not sended,
and the JOIN Node receive just one array to join with no other array!

So the "function Node" to set the GSHEET array, does not receive the "msg.payload.DHTEsterno"

I make a image with the array that the "function Node" receive:
Is showed the correct complete (GREEN) array and the array without the DHTEsterno (RED )

Please insert code inline, not in screenshots. Where I put
// do the undefined thing
//do the defined thing
those are comments where you must put the appropriate code. Since you have done nothing to prevent it trying to use DHTEstreno when it is undefined you are still getting the error.

A useful trick in this sort of situation is to use the nullish coalescing operator (??), which yields the second operand if the first is null or undefined.

const a = msg.payload.DHTSala[0].payload ?? 'no data'

The ordinary boolean OR (||) would work, but only if the first operand is not 0.

I hadn't seen that before, though I think it will come in useful for statements like
const x = context.get("x") ?? "something"
where it may be better than using || which fails if 0 or false is ever a valid value for x

I don't think that a solution here though, as the problem is that it is DHTSala that may be missing. For this I think it is optional chaining that is required. So the code would be
const a = msg.payload.DHTSala?.[0]?.payload
which will return undefined if DHTSala or DHTSala[0] do not exit

In fact if a particular value was required in this case then the two could be combined
const a = msg.payload.DHTSala?.[0]?.payload ?? "no data"
Which will return "no data" if anything on the left hand side does not exist.

yes - it is only supported in nodjs14 onwards - and as until this year we supported node12 we haven't been able to rely on it in the core so not really mentioned it in answers either... indeed as was optional chaining that we are now seeing more of :slight_smile:

You are probably right, although I haven't had a chance to test. I assumed that ?? would treat a missing object or property as undefined, but I may have assumed too much.

It fully evaluates the code to the left of ?? before testing for undefined, so if DHTSala does not exist then an error is generated when attempts to access [0] of it. The '?.' syntax evaluates up to that operator then if undefined it terminates the evaluation with undefined, so it never tries to evaluate the [0]. If not undefined then it evaluates [0] and then the next '?.' checks that for undefined, and so on.

Got it, thanks. Now I understand the syntax and, I guess, why it's called "chaining."

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