Search code examples
flaskchart.jsjinja2

ChartJS doesnt display labels provided by Jinja variable


I would like to use Flask to render a ChartJS graph. This is from my routes.py

@app.route("/graph")
def graph():
    d = Eval.query.all()
    labels = [i.date.strftime('%d.%m.%Y') for i in d]
    data = [i.bw for i in d]
    return render_template('chart.html', title='Charts', labels = labels, data = data) 

I've the following code in the chart.html:

{% extends "base.html" %}
{% block content %}

<canvas id="myChart" height="400" width="800"></canvas>
<script src="https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.4.0/Chart.min.js"></script>

<script type="text/javascript">
var ctx = document.getElementById('myChart').getContext('2d');
var chart = new Chart(ctx, {
  type: 'line',
  data: {
  labels: ['16.07.2017', '23.07.2017', '30.07.2017', '06.08.2017', '13.08.2017'],
  datasets: [{
      label: "My First dataset",
      backgroundColor: 'rgb(255, 99, 132)',
      borderColor: 'rgb(255, 99, 132)',
      data: {{ data }} 
   }]
  },
  options: {
    responsive:false
   }
});
</script>

{% endblock %}

with this code the chart is rendered with the correct labels.

Question:

However once I change the labels to

 labels: {{ labels }}

the chart is not rendered at all.

I checked to make sure that the {{ labels }} expression is indeed also a list with the correct formating. Calling {{ labels }} above the script tag shows the following output in the html page:

['16.07.2017', '23.07.2017', '30.07.2017', '06.08.2017', '13.08.2017']

Solution

  • If you are not using safe filter special symbols would be escaped during template parsing process and would corrupt the variable value.

    In the case above, final variable value without 'jinja safe' filter would be

    ["16.07.2017", "23.07.2017"] =>[&#39;16.07.2017&#39;,&#39;23.07.2017&#39;]
    

    And that value ([&#39;16.07.2017&#39;,&#39;23.07.2017&#39;]) is illegal for JS and you'll be able to see the error in the browser console:

    Uncaught SyntaxError: Unexpected token &
    

    In the case above, final variable value with 'jinja safe' filter would be the same

    ["16.07.2017", "23.07.2017"] =>["16.07.2017", "23.07.2017"]
    

    You can read more about escaping here.