1

I'm working with a partner on a project using Flask, which needs to pass a (variable) JSON object from the HTML file to the app.py file and thereby query our database. My partner successfully coded a version of this using text input fields, printing the retrieved records to the console. However, we've since changed things around quite a bit while implementing dropdown menus, and we have not been able to get things working correctly again.

As it currently stands, I am able to ping the app.py file and return a dummy response (e.g. printing "hello" to the console), but I can't seem to access the actual data that I pass in via the JSON object. (I haven't even messed with the database yet -- just trying to manipulate the object.) Most recently, I'm getting a GET (url) 500 (INTERNAL SERVER ERROR), and the same thing when I use POST method.

I've read a lot of discussions of similar problems (here, here, and here, to name a few) and have tried a couple of different approaches. I think I must be doing something wrong with the form, and it seems like the solution should be fairly simple, but I am not having much luck in figuring it out.

Here is the relevant HTML and Javscript:

<!-- establish the Flask form which will send the selected airports to the Python code and database -->
<form name="selected_route" id="selected_route" method="GET">

    <p>Departure</p>
    <p>
        <!-- dropdown menu for departure state -->
        <select name="departure_state" id="departure_state" onChange="changeDepAirport(this.value);">
        </select>

        <!-- dropdown menu for departure airport, generated by choice of state -->
        <select name="departure_airport" id="departure_airport">
        <option value="" disabled selected>Select an airport</option>
        </select>
    </p>

    <p>Arrival</p>
    <p>
        <!-- dropdown menu for arrival state -->
        <select name="arrival_state" id="arrival_state" onChange="changeArrivAirport(this.value);">
        </select>

        <!-- dropdown menu for arrival airport, generated by choice of state -->
        <select name="arrival_airport" id="arrival_airport">
        <option value="" disabled selected>Select an airport</option>
        </select>
    </p>

    <!-- submit button for the departure and arrival parameters, which will visualize the data for that route -->
    <p>
        <button name="go" id="go" type="submit" onclick="retrieveRouteData()">Go!</button>
    </p>
</form>

<script>
// function to retrieve the data for the selected route
function retrieveRouteData() {
    departure_airport = document.getElementById("departure_airport").value;
    arrival_airport = document.getElementById("arrival_airport").value;
    route_object = { "departure_airport" : departure_airport,
                        "arrival_airport" : arrival_airport};
    console.log(route_object);

    testAj(function(output){
        console.log("1")
        console.log(output)
    });

    function testAj(handleData) {
        $(document).ready(function() {
            $('form').submit(function (e) {
                var url = "{{ url_for('test') }}"; // send the data here
                $.ajax({
                    type: "GET",
                    url: url,
                    data: route_object,
                    success: function (data) {
                        console.log(data)  // display the returned data in the console.
                    }
                });
                e.preventDefault(); // block the traditional submission of the form.
            });
        });
    };
 };

 generateStateLists(); // calls the function to populate the initial dropdowns

 </script>

And here is the Python code:

from flask import Flask, jsonify, render_template, redirect, url_for, g, Response, request
from flask_cors import CORS
from flask_wtf import FlaskForm
from wtforms import StringField
from pymongo import MongoClient
from bson import json_util
from bson.json_util import dumps
import json
import os

app = Flask(__name__)
app.secret_key = ####

@app.route('/')
def home():
    print("come to home")
    return render_template('home.html')

# send json file
@app.route('/send')
def send():
    return "<a href=%s>file</a>" % url_for('static', filename='StateCityCode.json')


@app.route('/test', methods=['GET'])
def test():
    data = request.get_json()
    return data

if __name__ == '__main__':
    app.run(host='0.0.0.0',debug=True)

Thank you in advance for the help!

csdolling
  • 13
  • 1
  • 4

3 Answers3

0

Try stringifying the json data before sending and setting the json header for the call explicitly like this:

$.ajax({
                    type: "POST",
                    dataType: "json",
                    url: url,
                    data: JSON.stringify(route_object),
                    contentType: "application/json;charset=utf-8"
                    success: function (data) {
                        console.log(data)  // display the returned data in the console.
                    }
                });
Pedro Borges
  • 1,240
  • 10
  • 20
0

With flask, you can access HTML form elements easily. Check out the following code.

HTML:

<form action="" method="POST">
    <label> Username </label>
    <input type="text" name="username" value={{request.form.username}}>
    <label> Password </label>
    <input type=”"password" name="password" value={{request.form.password}}>

    <button type=”submit”> Submit </button>
</form>

Python:

def login()
    if request.method == 'POST':
        username = request.form['username']
        password = request.form['password']

        # code that uses the data you've got
        # in our case, checking if the user exists
        # and logs them in, if not redirect to sign up
    else:
        # an exception

Basically, you can access the element through the request.form that should connect to the database.

EDIT: If you want to search the form elements directly in Python, you can use the following code:

import cgi
form = cgi.FieldStorage()
searchterm =  form.getvalue('username')
searchterm =  form.getvalue('password')
  • This makes sense to me, and I had tried this syntax previously based on another discussion I'd found, but still with no luck. The solution below worked for me, but it seems like this one would also be useful if someone else comes across this question. Thanks for your help! – csdolling Nov 28 '18 at 15:08
0

I think the issue occurs in your code in the following line:

var url = "{{ url_for('test') }}"; // send the data here

In order to use Jinja to pass data to javascript you may need to escape the data. See here

Try and print out the value of url in your javascript code and see if the url is correct

vi_ral
  • 369
  • 4
  • 19