Cannot read properties of undefined (reading 'value') and Cannot read properties of undefined (reading ' metadata')

My current payload is this:

[ { "variable": "segundo", "value": 9, "minuto": 45, "hora": 13, "dia": 4, "mes": 12, "ano": 23, "valor": 6486, "metadata": { "mqtt_topic": "mensagem/json" } } ]

When I use emulator to send it so I can get the variables of a date and a application value on my bucket (because the same payload was being sent from my device but it was taking too much time to test), it returns the error in the title.

Solutions I tried:

- Emulating with the format it should have AFTER passing my personal parser below:

const ignore_vars = ['minuto','hora','dia','mes','ano','valor'];const minuto = payload.find((x) => x.variable === 'minuto');const hora = payload.find((x) => x.variable === 'hora');const dia = payload.find((x) => x.variable === 'dia');const mes = payload.find((x) => x.variable === 'mes');const ano = payload.find((x) => x.variable === 'ano');const valor = payload.find((x) => x.variable === 'valor');const segundoIndex = payload.findIndex((x) => x.variable === 'segundo');if (segundoIndex !== -1 && !payload[segundoIndex].hasOwnProperty('metadata')) {  payload[segundoIndex].metadata = {}}payload[segundoIndex].metadata.minuto = minuto.value;payload[segundoIndex].metadata.hora = hora.value;payload[segundoIndex].metadata.dia = dia.value;payload[segundoIndex].metadata.mes = mes.value;payload[segundoIndex].metadata.ano = ano.value;payload[segundoIndex].metadata.valor = valor.value;// Remove unwanted variables.payload = payload.filter(x => !ignore_vars.includes(x.variable));

steps taken from the topic Sending as much data as you want for the price of 1 data input

(the parser is active)

The parser, in theory, should change the payload to something like:

(I mean, that’s what I understood, this method didn’t work for me yet)

[    {        "variable": "segundo",        "value": 10,        "metadata": {            "mqtt_topic": "mensagem/json",            "minuto": 5,            "hora": 13,            "dia": 4,            "mes": 12,            "ano": 23,            "valor": 6486        }    }]

- Reducing the payload

[    {        "variable": "segundo",        "value": 10,        "metadata": {            "mqtt_topic": "mensagem/json"        }    }]

- Removing the metadata for this case of having reduced the payload:

[    {        "variable": "segundo",        "value": 10      }]

- Removing the value (idk, maybe it suddently worked?)

[    {        "variable": "segundo",               "metadata": {            "mqtt_topic": "mensagem/json",                    "minuto": 5,            "hora": 13,            "dia": 4,            "mes": 12,            "ano": 23,            "valor": 6486        }    }]
[    {        "variable": "segundo",        "minuto": 5,        "hora": 13,        "dia": 4,        "mes": 12,        "ano": 23,        "valor": 6486,        "metadata": {            "mqtt_topic": "mensagem/json"        }    }]

- Loading an example

[  {    "variable": "payload",    "value": "0109611395",    "metadata": {      "mqtt_topic": "mensagem/json"    }  }]

None of these solutions worked. The error keeps the same. In some cases, it changes to TypeError: Cannot read properties of undefined (reading ‘metadata’)

but that’s in moments like when I had the variables with upper case, such as “Ano” or in the last solution I tried

Please help me!

Hi Marcos,

In order for you to add data to your device bucket it needs to follow this format.

Example:

[

{

“variable”: “segundo”,

“value”: 9,

“metadata”: {

“mqtt_topic”: “mensagem/json”,

“minuto”: 45,

“hora”: 13,

“dia”: 4,

“mes”: 12,

“ano”: 23,

“valor”: 6486

}

}

]

If you can’t add this variable to your device’s bucket, you might’ve introduced an error within your device payload parser. I’d suggest debugging it using the example above.

I followed your example and read the topic. It seems my payload is in the valid format.

How can I debug my parser? All I know is use the emulator, but I don’t know if the simulations pass through the parser..

Hi Marcos,

You can debug your parser by running it using nodejs in your terminal. This will allow you to locate where the issue is.

One thing I noticed in your code is that you’re attempting to get multiple variables but this wont work since;

Here you have a single variable:

[

{

"variable": "segundo",

"value": 9,

"metadata": {

  "mqtt\_topic": "mensagem/json",

  "minuto": 45,

  "hora": 13,

  "dia": 4,

  "mes": 12,

  "ano": 23,

  "valor": 6486

}

}

]

if you send this through your device payload parser, it will stop working at line since you don’t have these variables in the payload:

const minuto = payload.find((x) => x.variable === ‘minuto’);

const hora = payload.find((x) => x.variable === ‘hora’);

const dia = payload.find((x) => x.variable === ‘dia’);

const mes = payload.find((x) => x.variable === ‘mes’);

const ano = payload.find((x) => x.variable === ‘ano’);

const valor = payload.find((x) => x.variable === ‘valor’);

So when the code attempts to get the value here:

payload[segundoIndex].metadata.minuto = minuto.value;

payload[segundoIndex].metadata.hora = hora.value;

payload[segundoIndex].metadata.dia = dia.value;

payload[segundoIndex].metadata.mes = mes.value;

payload[segundoIndex].metadata.ano = ano.value;

payload[segundoIndex].metadata.valor = valor.value;

It wont work and will display the error you are reporting.

Alright, I will try using nodejs later (never done it before omg), but

my payload isn’t that, that is what I think it should look after passing through the parser, which I only tested in the emulator.

My device sends this payload:

[
    { "variable": "segundo",
    "value": 9,
    "minuto": 45,
    "hora": 13,
    "dia": 4,
    "mes": 12,
    "ano": 23,
    "valor": 6486,
    "metadata":
       {
        "mqtt_topic": "mensagem/json" }
       }
 ]

I have the feeling something is wrong with the device configuration (which is weird, because it worked before) because not even the examples are working…

Marcos, you need to follow the format of [ { variable, value, time, metadata }… ], any other key in your object will be discarded. Any data, either real or emulating, will pass thru the parser of the device, and it will break. Of course, If you test it using vanilla NodeJS, you can manipulate the payload however you like, but you have to follow the Tago format and thus we’re not exactly in vanilla.

As Freddy said, I suggest to you to put the other values into the metadata, there you can have any data you want, in any format or schema. His first answer has already the data formated that way.

Other way is to split each value into their separate object in the array, and group them by the same ID. And other way is just to use the time parameter as intended, using a ISO8601 string.

I found where the issue is, but I have no idea of how to fix.

The problem is in my parser.

The variables ‘x’, or ‘item’, aren’t declarated.

So when I do

const minuto = payload.find((x) => x.variable === 'minuto');

‘minuto’ doesn’t receive anything, and when I go to the line

payload[segundoIndex].metadata.minuto = minuto.value;

there’s no value.

How to fix it? I mean, what is supposed to be ‘x’ or ‘item’?

(item is what appears in the reference https://help.tago.io/portal/en/kb/articles/147-payload-parser, and x from https://community.tago.io/t/sending-as-much-data-as-you-want-for-the-price-of-1-data-input-21-1-2022)

I tried the code below:

const ignore_vars = ['minuto','hora','dia','mes','ano','valor'];
//const rawValues = payload.find(item => item.variable === "variable");const rawValues = payload.find(item => item.variable === "metadata");if(rawValues){  const valuesString = rawValues.value;   const splitValues = valuesString.value.split(',');  const minuto = splitValues[0];  const hora = splitValues[1];  const dia = splitValues[2];  const mes = splitValues[3];  const ano = splitValues[4];  const valor = splitValues[5];payload.push({"variable": "Minuto", "value": minuto});payload.push({"variable": "Hora", "value": hora});payload.push({"variable": "Dia", "value": dia});payload.push({"variable": "Mes", "value": mes});payload.push({"variable": "Ano", "value": ano});payload.push({"variable": "Potencia", "value": valor});console.log("Teste");}payload = payload.filter(x => !ignore_vars.includes(x.variable));

Now it only considers the first variable, like if there had no parser.

It does not enter the condition.

Please print whatever you have on rawValues.

console.log({ rawValues })

You’re treating “metadata” as it was a variable named metadata. If that the case, you’re good to go, but I have a hunch it’s not.

Also, you can share your current raw payload.

Adding console.log({rawValues}); that’s what shows.

That’s why I am asking what is ‘item’ or ‘x’ because they don’t seem to have any values

Hi Marcos,

Did you manage to fix your Payload parser?
Item or X is just a reference to what is within the “Payload”:

“const rawValues = payload.find(item => item.variable === “metadata”);”

So if you have a list of objects, within your payload array, the “item” or “x” will be the object and you are looking for the object’s variable key: “metadata”.

I’m moving to thingsboard.

Thanks for the support