1

I've looked through many topics on stackoverflow, github, Google and many more... and found many different answers although no simple answer.

I'm writing a Facebook game in JavaScript (using melonJS engine). The framework is Flask (Python).

What I am trying to do, is to have ability to send data between Python and JS code with no need to refresh the page (like database operations, email sending, etc.). I want the user just to see the game, choose options, play and the game does the rest.

While I have managed to see that something like below will work:

app.py

def add(f,l,a):
    g.db.execute('insert into persons (fname,lname,age) values (?, ?, ?)',
            [f,l,a])
    g.db.commit()

@app.route('/')
def index():
    cur = g.db.execute('select fname, lname, age from persons order by id desc')
    entries = [dict(fname=row[0], lname=row[1], age=row[2]) for row in cur.fetchall()]
return render_template('app.html',entries=entries,addtodb=add)

app.html

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">

<head>
    <title>THE GAME</title>
    <meta http-equiv="content-type" content="text/html;charset=utf-8" />
    <meta name="generator" content="Geany 1.22" />

    <script type="text/javascript" src="jquery-1.7.1.min.js"></script>
    <script type="text/javascript">
    var adddb = '{{addtodb('Anne','Monk','12')}}';
    </script>

</head>

<body>
{{addtodb('Allie','Monk','78')}}
<ul class=entries>
        {% for entry in entries %}
            <li><h2>{{ entry.fname }} {{ entry.lname|safe }} </h2> Age: {{ entry.age }}</li>
        {% else %}
            <li><em>Unbelievable. No entries here so far</em></li>
        {% endfor %}
</ul>
</body>

</html>

And both the {{addtodb}} will work. I just wonder how to send the function to file.js that will be only linked to the HTML (like jquery above), not put directly inside. The "{{...}}" will not work as I already checked. I suppose I have to find some module to Python or use AJAX maybe, except I have no idea where to start.

Archarachne
  • 235
  • 1
  • 5
  • 18

2 Answers2

1

The answer is "AJAX", but hopefully some simplified elaboration will help point you in the right direction:

You need to make some kind of JS event (clicking a link, clicking a button, an event firing in your game) trigger an asynchronous (i.e. doesn't wait for the server's response) or synchronous (i.e. wait to hear back) call to a Flask endpoint on the server (i.e. the route you set up) with a request. If you're creating a new entry, that's probably a POST request. Validate it on the server and save it to the database.

If you also want the page to reflect anything that happened as a result of the server's behavior with the database, your Flask endpoint needs to return a JSON response. Since you already generated the HTML and JS that's on the page, a function in the JS needs to be bound as an event listener so it is looking for that JSON response, then parses the JSON and executes whatever code you put in the function.

JQuery's ajax functionality does that all for you. Here is an example of a jQuery AJAX POST. It doesn't matter that the example uses PHP; you parse the POST normally in your Flask view and return jsonify(data). See docs on Flask.jsonify.

Community
  • 1
  • 1
Josh Klein
  • 142
  • 6
  • Thank you very much for the answer. With your help and few other posts I started trying to work this out, but I have a problem with Flask. Where should I put the file with function code in the project folder? Because when I put the function in test.py in the main folder and put 'url: test.py' it always searches for the file in localhost:5000/test.py (I use foreman for testing). And I always get 404 - Not Found. My .js file is in /static folder. – Archarachne Feb 19 '13 at 17:07
  • 1
    Flask is built on top of Werkzeug, which works as a "gateway". It is not like writing one-off scripts. You are creating a Flask app that hears the browser's request and decides what to do. So when you point to test.py like that, nothing is happening because there is no file being served there. You need to create a [route](http://flask.pocoo.org/docs/quickstart/#routing) and point to that. You should really read the whole [quickstart](http://flask.pocoo.org/docs/quickstart/), and preferably the entire Flask documentation. It is not like writing scripts. – Josh Klein Feb 25 '13 at 21:11
  • Thank you for all your help. I have found the solution at last and can proceed with my work. :) – Archarachne Feb 27 '13 at 16:19
0

You have to use AJAX. On the server side, you just need a URL that returns your data in JSON form. On the client side, I suggest you use jQuery for AJAX requests. Just request the data from the server with jQuery and render the data into the DOM.

Linuxios
  • 34,849
  • 13
  • 91
  • 116