gromiczek
gromiczek

Reputation: 3020

How to access an array (JSON) in the front-end JavaScript that was passed by Python (Flask)?

I'm a real noobie using the Flask framework (and client-server generally), so bear with me. I have a basic HTML template file with a bit of Flask (uses the {% ... %} notation) passing in a JSON object from a python file. Right now, as a simple sanity check it's outputting the content of motifs (an array of arrays) as separate lines (<li>) in an unordered list (<ul>).

What I want it to do instead is use the motifs array of arrays in a JavaScript script as data for a visualization I'm trying to do. I tried mingling the Flask script into a JavaScript <script> tag that iterates out a JavaScript array, but got an error that the script tag didn't like the Flask notation (Uncaught SyntaxError: Unexpected token }. So how do I get the Flask script to cough up the array for use in a JavaScript script? I realize I may be misunderstanding some things here (perhaps the nature of JSONs?). I'd be grateful for any nudges in the right direction. Thanks!

Below I've included my html template with the Flask script creating the unordered list, I've also included my failed attempt to use the Flask script in a <script> tag. So how do I successfully access the array (JSON) in a JavaScript?

index.html (a template file - simplified here for clarity):

<!DOCTYPE html>
<head>
<title></title>
</head>
<body>

<p>Here are some motifs:</p>
    <ul>
        {% for motif in motifs %}
        <li>{{motif}}</li>
        {% endfor %}
    </ul>
<script>one of a few js scripts</script>
</body>
</html>

The output of the above file looks like this (missing the bullet points which didn't copy):

Here are some motifs:

{'gene1': 1, 'gene2': 1, 'gene3': 7, 'gene4': 7, 'gene5': 1}

{'gene1': 7, 'gene2': 4, 'gene3': 10, 'gene4': 5, 'gene5': 2}

{'gene1': 7, 'gene2': 1, 'gene3': 8, 'gene4': 5, 'gene5': 8}

{'gene1': 2, 'gene2': 4, 'gene3': 6, 'gene4': 1, 'gene5': 9}

{'gene1': 3, 'gene2': 8, 'gene3': 2, 'gene4': 7, 'gene5': 8}

{'gene1': 1, 'gene2': 5, 'gene3': 1, 'gene4': 9, 'gene5': 5}

{'gene1': 3, 'gene2': 5, 'gene3': 6, 'gene4': 10, 'gene5': 9}

{'gene1': 2, 'gene2': 10, 'gene3': 7, 'gene4': 5, 'gene5': 10}

{'gene1': 5, 'gene2': 5, 'gene3': 10, 'gene4': 10, 'gene5': 5}

{'gene1': 10, 'gene2': 4, 'gene3': 4, 'gene4': 6, 'gene5': 4}

Below is my failed attempt to access in a <script> the array (JSON object) passed by Flask:

<script>
var motifValuesArray = [];
var index = 0; // an iterator to assign indexes in the javascript array
{% for motif in motifs %}
    motifValuesArray[index] = {motif};
    console.log(motifValuesArray[index]);
{% endfor %}        
</script>

Upvotes: 2

Views: 5420

Answers (2)

AlexLordThorsen
AlexLordThorsen

Reputation: 8488

So the reason your <script> attempt failed is because you're attempting to run jinja2 code (the templating engine that comes with flask by default) in the web browser. The web browser doesn't have a python interpreter let alone a templating engine that is built on top of python.

With that being said there are several ways in which you can get a JSON array from flask to the client. Probably the simplest way is to pass the array as straight HTML and parse the html. But that's not very slick and can be very slow if your array gets very large.

Just to be thorough, this SO answer goes through how to do things straight from jinja2.

For my example I'm going to create a javascript function which is called on page load. This javascript function makes an ajax call to the flask application, receives a array in a JSON format, and finally parses the object to return the array.

Javascript

$(document).ready(function() {
    var request = $.ajax({
        type: "POST",
        url: "/example_array/",
        data: {"name":""}, // if you wanted to specifiy what list then pass an actual name
        dataType: "html"
    });

    request.done(function(JSON_array) {
        array_data = JSON.parse(JSON_array)["array"]
        //from here you have your array to play with
    });
});

flask file

from flask import jsonify

@app.route("/example_array/")
def example():
    list = get_list() # however you get your list data, put it here
    return jsonify(array=list)

@app.route("/")
def index():
     return render_template("home_page.html")

Upvotes: 3

Kyle Kelley
Kyle Kelley

Reputation: 14144

Use json.dumps to make sure that your motif dictionaries are proper JSON.

try: 
  import simplejson as json
except:
  import json

...

motifValuesArray[index] = {{json.dumps(motif)}};

Upvotes: 0

Related Questions