"TypeError: Cannot set properties of undefined (setting 'snr')"

Hello.

I have strange and interesting behaviour of function node. Script in Function node is only to form payload. In most cases it gives correct payload, but sometimes gives error "TypeError: Cannot set properties of undefined (setting 'snr')". snr parameter is always present in same format and path. Script is following:

var device_id = msg.payload.end_device_ids.device_id;
var gateway_id=msg.payload.uplink_message.rx_metadata[0].gateway_ids.gateway_id
var snr=msg.payload.uplink_message.rx_metadata[0].snr
var rssi=msg.payload.uplink_message.rx_metadata[0].rssi
var sf=msg.payload.uplink_message.settings.data_rate.lora.spreading_factor

msg.payload.uplink_message.decoded_payload["snr"] = snr
msg.payload.uplink_message.decoded_payload["rssi"] = rssi
msg.payload.uplink_message.decoded_payload["sf"] = sf
msg.payload.uplink_message.decoded_payload["gateway_id"] = gateway_id

fields=msg.payload.uplink_message.decoded_payload
tags = {
//        "timestamp" : timestamp,
        "device_id" : device_id,
}
msg.payload=[fields, tags]
return msg;

This problem relates to snr value only.
Is there any reasonable explanation or solution to this error?

Thank You.

Hi @Roberto69

The error will be coming from the line:

msg.payload.uplink_message.decoded_payload["snr"] = snr

This is the first time you are accessing msg.payload.uplink_message.decoded_payload - so this suggests that property doesn't exist on the message the function has received.

Hi @knolleary

I guess this is beacuse snr is before other parameters - if rssi would be first, than error will relate to rssi?

How can I avoid this?

@Roberto69 that error is saying msg.payload.uplink_message.decoded_payload is NOT "something"

You have a few choices:

  1. check it is empty & throw an error or return
  2. create it if it is empty
  3. skip it if empty

1

if (!msg.payload?.uplink_message?.decoded_payload) {
    node.error("msg does not contain decoded_payload", msg)
    return
}

2

if (!msg.payload?.uplink_message?.decoded_payload) {
    msg.payload.uplink_message = msg.payload.uplink_message || {}
    msg.payload.uplink_message.decoded_payload = {}
}

3

if (msg.payload?.uplink_message?.decoded_payload) {
    msg.payload.uplink_message.decoded_payload.snr = snr
    msg.payload.uplink_message.decoded_payload.rssi = rssi
    msg.payload.uplink_message.decoded_payload.sf = sf
    msg.payload.uplink_message.decoded_payload.gateway_id = gateway_id
}

That is right.

Do you expect msg.payload.uplink_message.decoded_payload to already exist on the message or is this a new property you are wanting to create?

If its a new thing, then you can do the following to create that object with the four properties set on it:

msg.payload.uplink_message.decoded_payload = {
    snr,
    rssi,
    sf,
    gateway_id
}