2

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>
gromiczek
  • 2,970
  • 5
  • 28
  • 49
  • Can you add an example of the generated HTML/Javascript? – Kyle Kelley Sep 16 '13 at 19:24
  • @Kyle - above I gave an example of the text outputted in the
      , though I would like it to be converted to a JS array rather than printed on screen. Does that make sense?
    – gromiczek Sep 16 '13 at 19:27
  • @myusuf3 - This question isn't really a duplicate. The author clearly knows how to pass data from Flask to javascript -- they need help with getting it in the right format for JSON, arrays. – Kyle Kelley Sep 16 '13 at 19:29
  • @gromiczek - I was curious to see rendered content to see what issues are coming up. You could always inject the entire motifs array as JSON and then break it into an array `motifs = {{json.dumps(motifs)}};` – Kyle Kelley Sep 16 '13 at 19:32
  • @ myusuf3 's duplicate reference in his comment above is a much better duplicate reference than the one currently referenced. Can someone with the duplicate marking privilege change the duplicate reference? Thanks! – gromiczek Sep 16 '13 at 19:39
  • Actually, I'm now making more headway with @Rawrgulmuffin 's answer below. – gromiczek Sep 17 '13 at 20:43

2 Answers2

3

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")
Community
  • 1
  • 1
AlexLordThorsen
  • 8,057
  • 5
  • 48
  • 103
  • Thanks for you help! I have the code implemented but have a bug now. Is there a curly brace or two or a parenthesis missing in the JavaScript example? I'm not sure exactly where each function should begin and end. Thanks! – gromiczek Sep 17 '13 at 16:59
  • Ah, thanks!! I have it up and running, though it prints to the screen and I can't figure out how it's doing that. I'd like to use the array in my JavaScript as a way of determining which images to display in a canvas, e.g. a value of 1 in the array determines that this image will display, a value of 2 in the array determines that a different image will display. How do I simply use it as data rather than printing it to the screen. Thanks so much for your help and time on this! – gromiczek Sep 17 '13 at 20:07
0

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)}};
Kyle Kelley
  • 13,804
  • 8
  • 49
  • 78
  • @ Kyle, thanks for your reply. The JSONs seem to be working fine (if that's what's being passed). It was the matter of getting them converted to a JS array. @myusuf3 's comment above linked to a person with the same question, so I think I'm on the right track now. Thanks! – gromiczek Sep 16 '13 at 19:32