Trying to get my dynamic json file in a markdown card, using a table

I am trying to get a dynamic json (number of rows can vary) in a markdown card, formatted in a HTML table (for later formatting)
after many iterations (and trail and error (mainly) I ended up with this piece of yaml for the card

type: markdown
title: Crypto Prices
content: >
  <table>
    <tr>
      <th>Token</th>
      <th>Value</th>
    </tr>
    {% for item in states.sensor.crypto_prices.state %}
      <tr>
        <td>{{ item.keys() | list | first }}</td>
        <td>{{ item.values() | list | first }}</td>
      </tr>
    {% endfor %}
  </table>

the json looks like this ( values adjusted for this post)

[{"XRP":373.41533359619996},{"SLP":13.73112431017001},{"SOL":507.3626683029},{"BTC":322.592982},{"DOGE":101.92951866014721}]

the configuration.yaml has the below to create the rest api

rest:
  - scan_interval: 30
    resource: https://<domain>/walletv2.php
    sensor:
      - name: Crypto Prices V2
        value_template: '{{ value_json }}'

All the card is doing is blinking (showing not showing), but zero values or keys are displayed.

What am I doing wrong?
Please assist where needed

I took your code and pasted it into my Template Editor like this:

{% set value_json =
{"XRP":373.41533359619996},{"SLP":13.73112431017001},{"SOL":507.3626683029},{"BTC":322.592982},{"DOGE":101.92951866014721}
%}
  <table>
    <tr>
      <th>Token</th>
      <th>Value</th>
    </tr>
    {% for item in value_json %}
      <tr>
        <td>{{ item.keys() | list | first }}</td>
        <td>{{ item.values() | list | first }}</td>
      </tr>
    {% endfor %}
  </table>

and it produces this:

<table>
    <tr>
      <th>Token</th>
      <th>Value</th>
    </tr>
    
      <tr>
        <td>XRP</td>
        <td>373.41533359619996</td>
      </tr>
    
      <tr>
        <td>SLP</td>
        <td>13.73112431017001</td>
      </tr>
    
      <tr>
        <td>SOL</td>
        <td>507.3626683029</td>
      </tr>
    
      <tr>
        <td>BTC</td>
        <td>322.592982</td>
      </tr>
    
      <tr>
        <td>DOGE</td>
        <td>101.92951866014721</td>
      </tr>
    
  </table>

So your JSON seems to be valid and your code seems appropriate. You’ll notice I substituted states.sensor.crypto_prices.state for value_json to make it work in the Template Editor, since I don’t have that sensor to work with. You may want to try using the more widely accepted format of states('sensor.crypto_prices') and see if that works. If not, I’d look very closely at the data written to that sensor. There is either a missing set of quotes, extra quotes or the more difficult to spot improper quotes. In essence, if your sensor encapsulates the JSON string with double quotes, there can be NO double quotes within that sting. They MUST be replaced with single quotes.

For example
"{{ state_attr('sensor.current_forecast', 'current_forecast') }}" is OK, but
'{{ state_attr('sensor.current_forecast', 'current_forecast') }}' will fail, as would
"{{ state_attr("sensor.current_forecast", "current_forecast") }}"

*** Note; this is just a quick example to illustrate my point, and not the data you would find in the JSON data, but the principal remains the same. You must encapsulate quoted data with the opposite type of quotes used within the data. Good luck!!

Edit In looking at some of my sensors with JSON data as a string, there are NO quotes, so it is possible that a rogue quote in your text could also break the code. Of course your dataset may be much bigger than the sample you provided so it’s impossible to check that at this point. try pasting your JSON data into this website: https://jsonlint.com and also this one to get the correct paths: https://jsonpathfinder.com

Here is the corrected JSON string:

{
    "XRP": 373.41533359619996,
    "SLP": 13.73112431017001,
    "SOL": 507.3626683029,
    "BTC": 322.592982,
    "DOGE": 101.92951866014721
}

Many thanks @kartcon for taking the time and effort looking into this
I have been working with your hints and tips through out the day and have come … almost nowhere sadly.
I am really confused as I have been working with json/xml and other data formats for a really long time now, and neve had a huddle this big to jump over.
New to HA and how data is processed, this is clearly due to me missing something crucial, somewhere.

  1. the JSON is valid and clean, no hidden special characters or " or ’ anywhere.
  2. tried different method iterating through the dataset, no luck.

Learned from the past, making things simple before complicating, I went back to the below code in the card.

type: markdown
title: Wallet value
content: |
  <table border=1>
    {% set wallet = states.sensor.crypto_prices_v2 %}
  <tr>
  <td>    {{ wallet }}   </td> 
  </tr>
  </table>

That is giving me am expected single cell with data
<template TemplateState(<state sensor.crypto_prices_v2=[{'XRP': 370.4321873322}, {'SLP': 13.458802627621148}, {'SOL': 489.61819747019996}, {'BTC': 316.06514364}, {'DOGE': 100.54670776689922}]; friendly_name=Crypto Prices V2 @ 2025-01-25T17:53:27.064513+01:00>)>

Hinting me to… nowhere.
google is not a great help on this, so trying the best of luck here once more.
else I will have to find a different way in the backend providing data differently, Would be sad if I have to move to this direction.

Thanks again for any hints and tips or examples, pushing me in the right way!

Can you post the entire value of sensor.crypto_prices_v2 or whatever sensor the rest command posts its data to. I’d like to create a local sensor with the full dataset so I can test. I do think you’re very close but missing something. I’m really thinking it has something to do with how the JSON is written to the sensor, so having the full dataset will allow me to better troubleshoot. I understand if you need to adjust the values for security or privacy reasons, just please do not remove anything that may nullify the dataset. Changing values should not affect the data, so that’s OK by me.

After a few trial and error @kartcon has found the solution to the problem.
The issue is to be found in the way HA is attacking the JSON it seems and parsing the JSON string as text, converting it into an array using split, removing unwanted characters while parsing through the lines, making them visible in the table.

A rather complex way to iterate through a valid JSON string, but it works!

Thanks again @kartcon for your help and guidance.

Below the final code “without markup for the table” for reference and use in the future, hoping this will help someone else!

type: markdown
title: Crypto Prices
content: |-
  <table>
    <tr>
      <td>Token</td>
      <td>Value</td>
    </tr>
  {% set dictstr = states('sensor.crypto_prices_v2').split(",") -%}
  {% set n = namespace(dict=[]) -%}
    {% for i in dictstr -%}
        {% set kvpair = i.split(":") -%}
        {% set n.key = kvpair[0]|replace("'","") | replace(" ","") | replace("[","") | replace("{","") -%}
        {% set n.val = kvpair[1]|replace(" ","") | replace("}","") | replace("]","") -%}
        <tr>
          <td>{{ n.key }}</td>
          <td>{{ n.val }}</td>
        </tr>
    {% endfor %}
  </table>
1 Like