Reputation: 107
I'm trying to pass information (a dictionary) from Javascript to Flask using an ajax call in my javascript file.
I'm running Python 2.7 on CentOS7.
The Flask route gets the data via request.get_json('data') and the dictionary is picked up by python because my console prints out the requested dictionary. I can access the dictionary, but I don't know why I get the typeError.
Here is my flask code:
# import the Flask class from the flask module
from flask import Flask, render_template, redirect, url_for, request, jsonify
import json
from ev import EventViewer
# create the application object
app = Flask(__name__, )
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 0
app.run(debug=True, host='localhost:5000')
@app.route('/')
def main():
return render_template('charts.html') # render a template
@app.route('/python_portal', methods=['GET', 'POST'])
def python_portal():
if request.method == "POST":
print 'STEP 1'
request_data = request.get_json('data')
print "query: %s" % request_data
page = request_data['page']
payload = request_data['data_to_pass']
print 'STEP 2'
print page, request_data
return "Python portal"
# start the server with the 'run()' method
if __name__ == '__main__':
app.run(debug=True)
Here is my Javascript:
function build(query){
var qu = query
console.log(qu)
$.ajax(
{
type: "POST",
async: true,
contentType: "application/json; charset=utf-8",
url: "/python_portal",
data: JSON.stringify(query),
dataType: "json",
failure: function () {
console.log("failure");
},
success: function (data) {
console.log("success");
for(i=0; i < 3; i++){
console.log(i);
};
}
})
};
$('#submit').on('click', function() {
var event_name = document.getElementById("schools").value;
var symbol_name = document.getElementById("vacations").value;
var instances = document.getElementById("instances").value;
var payload = {
"page": "project",
"data_to_pass": [event_name, symbol_name, instances]
}
build(payload)
})
Here is my html:
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<!-- Load c3.css -->
<link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.2/c3.css" rel="stylesheet">
<link rel="stylesheet" type="text/css" href="//maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<link rel="stylesheet" type="text/css" href="//cdnjs.cloudflare.com/ajax/libs/c3/0.4.10/c3.min.css"/>
<link rel="stylesheet" type="text/css" href="../static/css/style.css" >
<!-- Load d3.js and c3.js -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.9.7/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.2/c3.js"></script>
<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>
<script src="http://code.jquery.com/jquery-latest.js"></script>
</head>
<body>
<div class="container">
<div class="row">
<div class="col-8">
<div class="form-group w-50">
<input type="text" class="form-control" id="schools" placeholder="schools" >
<input type="text" class="form-control" id="vacations" placeholder="vacations">
</div>
</div>
</div>
<div class="row">
<div class="col-2">
<div class="form-group">
<label>Instances to lookback</label>
<select class="form-control" id="instances">
<option>1</option>
<option>2</option>
<option>3</option>
<option>4</option>
<option>5</option>
</select>
</div>
</div>
</div>
<div class="row">
<div class="col-4">
<button id="submit" class="btn btn-primary btn-sm" type="submit" onclick=build('chart') >Generate</button>
<div class="spinner-border spinner-border-sm d-none text-light" role="status" aria-hidden="true" id="spin0"></div>
</div>
</div>
</div>
<div class="container">
<div class="row">
<div class="col-md-12">
<div id="event_chart"></div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div id="event_chart2"></div>
</div>
<div class="col-md-6">
<div id="event_chart3"></div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<div id="event_chart4"></div>
</div>
<div class="col-md-6">
<div id="event_chart5"></div>
</div>
</div>
</div>
<script type="text/javascript" src="../static/js/chart.js"></script>
<script src="http://code.jquery.com/ui/1.10.2/jquery-ui.js" ></script>
</body>
</html>
The problem is that I get a
"TypeError: string indices must be integers"
on the dictionary. The strange part is that despite this error, the dictionary seems to be fine and I can access the (key,values) -- I just get that typeError in my flask console.
Here is the Flask console log showing the data and the error:
* Restarting with stat
* Debugger is active!
* Debugger PIN: 125-816-613
STEP 1STEP 1
query: chart
query: {u'data_to_pass': [u'', u'', u'1'], u'page': u'project'}
STEP 2
project {u'data_to_pass': [u'', u'', u'1'], u'page': u'project'}
127.0.0.1 - - [12/Jul/2019 10:35:51] "POST /python_portal HTTP/1.1" 200 -
127.0.0.1 - - [12/Jul/2019 10:35:51] "POST /python_portal HTTP/1.1" 500 -
Traceback (most recent call last):
File "/data/4/dfs/eqo/env/envs/py2/lib/python2.7/site-packages/flask/app.py", line 2328, in __call__
return self.wsgi_app(environ, start_response)
File "/data/4/dfs/eqo/env/envs/py2/lib/python2.7/site-packages/flask/app.py", line 2314, in wsgi_app
response = self.handle_exception(e)
File "/data/4/dfs/eqo/env/envs/py2/lib/python2.7/site-packages/flask/app.py", line 1760, in handle_exception
reraise(exc_type, exc_value, tb)
File "/data/4/dfs/eqo/env/envs/py2/lib/python2.7/site-packages/flask/app.py", line 2311, in wsgi_app
response = self.full_dispatch_request()
File "/data/4/dfs/eqo/env/envs/py2/lib/python2.7/site-packages/flask/app.py", line 1834, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/data/4/dfs/eqo/env/envs/py2/lib/python2.7/site-packages/flask/app.py", line 1737, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/data/4/dfs/eqo/env/envs/py2/lib/python2.7/site-packages/flask/app.py", line 1832, in full_dispatch_request
rv = self.dispatch_request()
File "/data/4/dfs/eqo/env/envs/py2/lib/python2.7/site-packages/flask/app.py", line 1818, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/home/ssohn/py/projects/flask_error/app.py", line 24, in python_portal
page = request_data['page']
TypeError: string indices must be integers
Upvotes: 2
Views: 525
Reputation: 41187
Posting an answer as this doesn't fit in a comment.
According to the output, sometimes request.get_json('data')
returns a string (e.g. "chart").
I don't know why this happens, so I suggest going around the problem, by changing the function to:
@app.route('/python_portal', methods=['GET', 'POST'])
def python_portal():
if request.method == "POST":
print 'STEP 1'
request_data = request.get_json('data')
print "query: %s" % request_data
if isinstance(request_data, (dict,)):
page = request_data['page']
payload = request_data['data_to_pass']
print 'STEP 2'
print page, request_data
return "Python portal - POST"
# ...
Upvotes: 1