Reputation: 710
I'm trying to send a list from python using Flask on a web server to a client with jinja and javascript. This should be simple using json. This is my python code:
@app.route("/demo")
def demo():
basket = [{"fruit": "apple", "amount": 3}, {"fruit": "pear", "amount": 1}, {"fruit": "kiwi", "amount": 2}]
return render_template("demo.html", basket=json.dumps(basket))
This is a simplified code, in the final program the list will be the result of a database query. The jinja template is as follows:
{% extends "layout.html" %}
{% block title %}
Demo
{% endblock %}
{% block main %}
<script>
console.log('{{ basket }}');
object = JSON.parse('{{ basket }}')
</script>
{% endblock %}
However, javascript returns a parsing error:
[{"fruit": "apple", "amount": 3}, {"fruit": "pear", "amount": 1}, {"fruit": "kiwi", "amount": 2}] demo:1 Uncaught SyntaxError: Unexpected token & in JSON at position 2 at JSON.parse () at demo:54
It seems that the double quote " is somehow translated to the HTML code " for the " character. Subsequently JSON.parse cannot handle that. Tried breaking up the list in two arrays 'fruit' and 'amount', same error. I'm guessing that the client doesn't know that I'm sending json and that I should set content-type to application/json. Is that right, and if it is, how and where should I do this?
UPDATE after Makozaki's answer: Passing 'basket' as a python object (instead of a json object) combined with a jinja for loop works, but only if you rebuild arrays of single elements:
<script>
fruit = [];
{% for item in basket %}
fruit.push('{{ item["fruit"] }}')
{% endfor %}
console.log(fruit)
</script>
Trying to push items consisting of 'fruit' and 'amount' will again contain all the escaped characters. And it seems silly that you would have to rebuild an array that is passed in its entirety as an object.
Turning off autoescape works as well, but in an unexpected way:
<script>
{% autoescape false %}
object = {{ basket }};
{% endautoescape %}
</script>
This returns exactly the object that is passed. But the funny thing is: you have to omit the single quotes before and after the double curly braces! (as opposed to the previous example)
Thanks for the inspiration!
Upvotes: 3
Views: 3347
Reputation: 4366
In short object|tojson|safe
is the way to do it, example from JSON Support.
<script type=text/javascript>
doSomethingWith({{ user.username|tojson|safe }});
</script>
Upvotes: 4