Flask and AJAX with Vanila JavaScript



examples/flask/21/app.py
from flask import Flask, jsonify, render_template, request
import time
app = Flask(__name__)

@app.route("/")
def main():
    return render_template('main.html', reload = time.time())

@app.route("/api/info")
def api_info():
    info = {
       "ip" : "127.0.0.1",
       "hostname" : "everest",
       "description" : "Main server",
       "load" : [ 3.21, 7, 14 ]
    }
    return jsonify(info)

@app.route("/api/calc")
def add():
    a = int(request.args.get('a', 0))
    b = int(request.args.get('b', 0))
    div = 'na'
    if b != 0:
        div = a/b
    return jsonify({
        "a"        :  a,
        "b"        :  b,
        "add"      :  a+b,
        "multiply" :  a*b,
        "subtract" :  a-b,
        "divide"   :  div,
    })

examples/flask/21/test_app.py
import app


def test_app():
    web = app.app.test_client()

    rv = web.get('/')
    assert rv.status == '200 OK'
    assert b'<button id="calc">Calc</button>' in rv.data

    rv = web.get('/api/info')
    assert rv.status == '200 OK'
    #print(rv.data) # the raw json data
    assert rv.headers['Content-Type'] == 'application/json'
    resp = rv.json
    assert resp == {
       "ip" : "127.0.0.1",
       "hostname" : "everest",
       "description" : "Main server",
       "load" : [ 3.21, 7, 14 ]
    }

    rv = web.get('/api/calc?a=7&b=8')
    assert rv.status == '200 OK'
    assert rv.headers['Content-Type'] == 'application/json'
    resp = rv.json
    assert resp == {
        "a"        :  7,
        "b"        :  8,
        "add"      :  15,
        "multiply" :  56,
        "subtract" :  -1,
        "divide"   :  0.875,
    }

    rv = web.get('/api/calc', query_string={ 'a' : '10', 'b': '2' })
    assert rv.status == '200 OK'
    assert rv.headers['Content-Type'] == 'application/json'
    resp = rv.json
    assert resp == {
        "a"        :  10,
        "b"        :  2,
        "add"      :  12,
        "multiply" :  20,
        "subtract" :  8,
        "divide"   :  5,
    }

examples/flask/21/static/math.js
(function() {
    var ajax_get = function(url, callback) {
        xmlhttp = new XMLHttpRequest();
        xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                console.log('responseText:' + xmlhttp.responseText);
                try {
                    var data = JSON.parse(xmlhttp.responseText);
                } catch(err) {
                    console.log(err.message + " in " + xmlhttp.responseText);
                    return;
                }
                callback(data);
            }
        };
 
        xmlhttp.open("GET", url, true);
        xmlhttp.send();
    };
 
    ajax_get('/api/info', function(data) {
        console.log('get info');
        document.getElementById('info').innerHTML = JSON.stringify(data, null, '   ');
        document.getElementById('description').innerHTML = data['description'];
    });
 
    var calc = document.getElementById('calc');
    calc.addEventListener('click', function() {
        document.getElementById('info').style.display = "none";
        document.getElementById('description').style.display = "none";
        var url = '/api/calc?a=' + document.getElementById('a').value + '&b=' + document.getElementById('b').value;
        //console.log(url);
        ajax_get(url, function(data) {
            document.getElementById('add').innerHTML = data['a'] + ' + ' + data['b'] + ' = ' + data['add'];
            document.getElementById('subtract').innerHTML = data['a'] + ' - ' + data['b'] + ' = ' + data['subtract'];
            document.getElementById('multiply').innerHTML = data['a'] + ' * ' + data['b'] + ' = ' + data['multiply'];
            document.getElementById('divide').innerHTML = data['a'] + ' / ' + data['b'] + ' = ' + data['divide'];
        });
    });
})()

examples/flask/21/templates/main.html
<html>
<head>
</head>
<body>
<input type="number" id="a">
<input type="number" id="b">
<button id="calc">Calc</button>
<div id="results">
   <div id="add"></div>
   <div id="subtract"></div>
   <div id="multiply"></div>
   <div id="divide"></div>
</div>

<pre id="info"></pre>
<div id="description"></div>

<script src="/static/math.js?r={{reload}}"></script>
</body>
</html>