6

I have Python code, in which I'm using jinja to send data to a template in Flask. I can access the code just find in HTML, but when I try displaying the data in Javascript, it doesn't work. For example, here's my Python code:

name = "Steve"
return render_template('simple.html',data=json.dumps(name))

And in my simple.html code, in the html body:

<script>
var name = {{ data }};
alert(name);
</script>

The error in my console says "SyntaxError: Unexpected token '&'"

I know I've seen this problem before, I'm forgetting how to solve it though.

Amanda_Panda
  • 1,156
  • 4
  • 26
  • 68

4 Answers4

15

Never mind, I got it. I needed to use safe to escape the code. Example:

<script>
var name = {{ data|safe }};
alert(name);
</script>
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
Amanda_Panda
  • 1,156
  • 4
  • 26
  • 68
10

Flask got a builtin filter tojson. Therefore we can do:

flask:

data = {
    "firstname": "Steve", 
    "lastname": "Jobs"
}
return render_template('simple.html', data=data)

jinja2:

<script type="text/javascript">
var data = {{ data | tojson }}; 
console.log(data);
</script>
Sean Vieira
  • 155,703
  • 32
  • 311
  • 293
aGuegu
  • 1,813
  • 1
  • 21
  • 22
  • 1
    Since all valid JSON is valid JS you can actually skip the `JSON.parse` step completely and just do `var data = {{ data | tojson }}; – Sean Vieira Jul 10 '15 at 14:24
  • Doing this not only make the code look safer, but also parse the json string to a JS object. And JS object is more equal to dict in python. – aGuegu Jul 13 '15 at 01:10
  • When a JSON object is written out in a script block (as it is when you do `var data = {{ data | tojson }}`) it will be interpreted as JavaScript by the browser. Since JSON is a subset of JavaScript the "JSON" that was written out into the script block will be interpreted as a normal JavaScript object by the browser (since JSON is only data, this is safe to do, as opposed to writing out any user-provided string into a script block, which is not safe). Passing the "JSON" as a JavaScript string to `JSON.parse` is just adding an extra unnecessary step. Does that make sense? – Sean Vieira Jul 13 '15 at 11:53
  • Got you. the single comma can be got rid of too. – aGuegu Jul 14 '15 at 03:27
  • I have editeb my answer. The old one is `var data = JSON.parse('{{ data | tojson }}');`. Thank you, @SeanVieira – aGuegu Jul 14 '15 at 03:35
  • how do i make this work if my javascript function is in a file under static/js? I tried – PYA Jan 14 '17 at 23:57
2

Use it like this.

<script type="text/javascript">
    var data = '{{ invoice.inv_num }}';
</script>

Just put quotes around it for data part.

ChandyShot
  • 177
  • 1
  • 3
0

I was having problems when trying to pass python lists from my Flask app to my external Javascript file (Python/Flask App -> HTML -> Javascript).

This is how I made it work...

app.py

from flask import Flask, render_template, request, redirect, json

@app.route("/login", methods=["POST"])
def login():

    max = 400

    bar_labels = ['JAN', 'FEB', 'MAR', 'APR',
                  'MAY', 'JUN', 'JUL', 'AUG',
                  'SEP', 'OCT', 'NOV', 'DEC']

    bar_values = [967.67, 1190.89, 1079.75, 1349.19,
                  2328.91, 2504.28, 2873.83, 4764.87,
                  4349.29, 6458.30, 9907, 16297]

    return render_template('profile.html', 
                            labels=json.dumps(bar_labels), 
                            values=json.dumps(bar_values), 
                            headings=headings, data=data)

profile.html

.
.
.
<script type="text/javascript"> window.max = JSON.parse({{ max | tojson }});
                                window.values = JSON.parse({{ values | tojson }});
                                window.labels = JSON.parse({{ labels | tojson }})</script>
<script src="{{url_for('static', filename='main.js')}}"></script>
.
.
.

main.js

window.onload=function(){
    console.log(max)
    console.log(labels)
    console.log(values)
};
Matheus Torquato
  • 1,293
  • 18
  • 25