[javascript] How can I pass data from Flask to JavaScript in a template?

My app makes a call to an API that returns a dictionary. I want to pass information from this dict to JavaScript in the view. I am using the Google Maps API in the JS, specifically, so I'd like to pass it a list of tuples with the long/lat information. I know that render_template will pass these variables to the view so they can be used in HTML, but how could I pass them to JavaScript in the template?

from flask import Flask
from flask import render_template

app = Flask(__name__)

import foo_api

api = foo_api.API('API KEY')

@app.route('/')
def get_data():
    events = api.call(get_event, arg0, arg1)
    geocode = event['latitude'], event['longitude']
    return render_template('get_data.html', geocode=geocode)

This question is related to javascript python flask jinja2

The answer is


Alternatively you could add an endpoint to return your variable:

@app.route("/api/geocode")
def geo_code():
    return jsonify(geocode)

Then do an XHR to retrieve it:

fetch('/api/geocode')
  .then((res)=>{ console.log(res) })

<script>
    const geocodeArr = JSON.parse('{{ geocode | tojson }}');
    console.log(geocodeArr);
</script>

This uses jinja2 to turn the geocode tuple into a json string, and then the javascript JSON.parse turns that into a javascript array.


Just another alternative solution for those who want to pass variables to a script which is sourced using flask, I only managed to get this working by defining the variables outside and then calling the script as follows:

    <script>
    var myfileuri = "/static/my_csv.csv"
    var mytableid = 'mytable';
    </script>
    <script type="text/javascript" src="/static/test123.js"></script>

If I input jinja variables in test123.js it doesn't work and you will get an error.


Using a data attribute on an HTML element avoids having to use inline scripting, which in turn means you can use stricter CSP rules for increased security.

Specify a data attribute like so:

<div id="mydiv" data-geocode='{{ geocode|tojson }}'>...</div>

Then access it in a static JavaScript file like so:

// Raw JavaScript
var geocode = JSON.parse(document.getElementById("mydiv").dataset.geocode);

// jQuery
var geocode = JSON.parse($("#mydiv").data("geocode"));

Well, I have a tricky method for this job. The idea is as follow-

Make some invisible HTML tags like <label>, <p>, <input> etc. in HTML body and make a pattern in tag id, for example, use list index in tag id and list value at tag class name.

Here I have two lists maintenance_next[] and maintenance_block_time[] of the same length. I want to pass these two list's data to javascript using the flask. So I take some invisible label tag and set its tag name is a pattern of list index and set its class name as value at index.

_x000D_
_x000D_
{% for i in range(maintenance_next|length): %}_x000D_
<label id="maintenance_next_{{i}}" name="{{maintenance_next[i]}}" style="display: none;"></label>_x000D_
<label id="maintenance_block_time_{{i}}" name="{{maintenance_block_time[i]}}" style="display: none;"></label>_x000D_
{% endfor%}
_x000D_
_x000D_
_x000D_

After this, I retrieve the data in javascript using some simple javascript operation.

_x000D_
_x000D_
<script>_x000D_
var total_len = {{ total_len }};_x000D_
_x000D_
for (var i = 0; i < total_len; i++) {_x000D_
    var tm1 = document.getElementById("maintenance_next_" + i).getAttribute("name");_x000D_
    var tm2 = document.getElementById("maintenance_block_time_" + i).getAttribute("name");_x000D_
    _x000D_
    //Do what you need to do with tm1 and tm2._x000D_
    _x000D_
    console.log(tm1);_x000D_
    console.log(tm2);_x000D_
}_x000D_
</script>
_x000D_
_x000D_
_x000D_


The ideal way to go about getting pretty much any Python object into a JavaScript object is to use JSON. JSON is great as a format for transfer between systems, but sometimes we forget that it stands for JavaScript Object Notation. This means that injecting JSON into the template is the same as injecting JavaScript code that describes the object.

Flask provides a Jinja filter for this: tojson dumps the structure to a JSON string and marks it safe so that Jinja does not autoescape it.

<html>
  <head>
    <script>
      var myGeocode = {{ geocode|tojson }};
    </script>
  </head>
  <body>
    <p>Hello World</p>
    <button onclick="alert('Geocode: ' + myGeocode[0] + ' ' + myGeocode[1])" />
  </body>
</html>

This works for any Python structure that is JSON serializable:

python_data = {
    'some_list': [4, 5, 6],
    'nested_dict': {'foo': 7, 'bar': 'a string'}
}
var data = {{ python_data|tojson }};
alert('Data: ' + data.some_list[1] + ' ' + data.nested_dict.foo + 
      ' ' + data.nested_dict.bar);

Some js files come from the web or library, they are not written by yourself. The code they get variable like this:

var queryString = document.location.search.substring(1);
var params = PDFViewerApplication.parseQueryString(queryString);
var file = 'file' in params ? params.file : DEFAULT_URL;

This method makes js files unchanged(keep independence), and pass variable correctly!


Working answers are already given but I want to add a check that acts as a fail-safe in case the flask variable is not available. When you use:

var myVariable = {{ flaskvar | tojson }};

if there is an error that causes the variable to be non existent, resulting errors may produce unexpected results. To avoid this:

{% if flaskvar is defined and flaskvar %}
var myVariable = {{ flaskvar | tojson }};
{% endif %}

Examples related to javascript

need to add a class to an element How to make a variable accessible outside a function? Hide Signs that Meteor.js was Used How to create a showdown.js markdown extension Please help me convert this script to a simple image slider Highlight Anchor Links when user manually scrolls? Summing radio input values How to execute an action before close metro app WinJS javascript, for loop defines a dynamic variable name Getting all files in directory with ajax

Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to flask

Flask at first run: Do not use the development server in a production environment Flask - Calling python function on button OnClick event python-How to set global variables in Flask? In Flask, What is request.args and how is it used? How to print from Flask @app.route to python console What does "app.run(host='0.0.0.0') " mean in Flask Making an asynchronous task in Flask Flask ImportError: No Module Named Flask can you add HTTPS functionality to a python flask web server? How to get http headers in flask?

Examples related to jinja2

'if' statement in jinja2 template Ansible: filter a list by its attributes Split string into list in jinja? How to iterate through a list of dictionaries in Jinja template? How to write dynamic variable in Ansible playbook Jinja2 template not rendering if-elif-else statement properly Jinja2 template variable if None Object set a default value Convert integer to string Jinja Link to Flask static files with url_for How to pass a list from Python, by Jinja2 to JavaScript