Template: Checking empty json object/array

Hi there,
I would like to parse my JSON data coming in via MQTT. I want to do this with a value_template.
But sometimes the JSON object contains something, but sometimes it is empty. How can I check if a JSON Object and/or a JSON Array is not empty?
Currently, unfortunately, I still get the following error, so I would like to fix that with this:
Error parsing value: dict object has no element 0

I hope you can help me and understand my ugly english :smile:

Thanks,
Dominic

Hi Dominic… I think you should give some more details. It would help sort out the problem.

Okay, sorry. So… sometimes I get the following response through MQTT:

{
    "header": {
        "messageId": "c72bcb4838eacd82911cd9d63c4ec685",
        "namespace": "Appliance.Control.ToggleX",
        "method": "PUSH",
        "payloadVersion": 1,
        "from": "/appliance/2007162237199990820048e1e92587cf/publish",
        "timestamp": 1612276065,
        "timestampMs": 654,
        "sign": "ed94787a2cb855ae5725aaf4f436f3de"
    },
    "payload": {
        "togglex": {
            "channel": 1,
            "onoff": 0,
            "lmTime": 1612276064
        }
    }
}

and sometimes the same, but with an empty payload:

{
    "header": {
        "messageId": "aa3a54e26083d086800b66b853b2aa38",
        "namespace": "Appliance.Control.ToggleX",
        "method": "SETACK",
        "payloadVersion": 1,
        "from": "/appliance/2007162237199990820048e1e92587cf/publish",
        "timestamp": 1612276064,
        "timestampMs": 607,
        "sign": "15226fce6f0f23967310ee67eb66ab39"
    },
    "payload": {}
}

I need the onoff value from the json.
Currently I’m doing this by using the following template code:

{{ value_json.payload.togglex[0].onoff }}

But it throws me the following exception when the payload of the response is empty:
Error parsing value: dict object has no element 0
So how can I check if the element size of the togglex array is not zero or if the payload is not empty?

payload will always be defined based on his JSON, so that won’t work.

In his case, if the dictionary is empty but defiend, a simple if value_json.payload will suffice. Also [0] elements never exist for dictionaries, the correct path to onoff is value_json.payload.togglex.onoff

{% if value_json.payload %}
  {{ value_json.payload.togglex.onoff }}
{% endif %}

I read your post, I guess I should have split it into 2. My reply to you was about the is defined not working because payload is defined. The rest was for OP.

Thanks to both of you @petro and @123.
You helped me a lot.

It’s true, I considered togglex as an array here, although it is an object in itself. This is because in yet another message togglex is an array. However, unlike in this case, the payload is never empty.
Thanks for bringing this to my attention. That was then probably also a mistake of mine, which is why my script did not work.

The following solution now works for me:

{% if value_json.payload.togglex is defined %}
  {{ value_json.payload.togglex.onoff }}
{%- else -%}
  {{ states('switch.meross_1') }}
{%- endif -%}

I go that {% if value_json.payload.togglex %} and {% if value_json.payload.togglex is defined %} in themselves do the same thing. But I have now deliberately chosen the second solution to make the code more understandable for me.

HA’s equivalent of watching two Chess Masters, Jinja Masters! I learn every time these folks code a new Jinja solution.

1 Like

Haha I thought the same thing after browsing several hours of forum posts and github issues :joy:

Yes exactly, I had tried that and then noticed that only one post can be marked as a solution. I took something from both of you and built my full solution from it, so I marked my post.
I would have liked to mark your post too, but this one is still missing the .togglex at the end in the if query.
I hope that’s okay with you guys.