How to send a single string to python function from ajax query - javascript

Context: I am using JavaScript to send a string as a parameter to a python function over the flask.
But I always get "the missing 1 parameter error" on the python side.
This is what my Ajax query looks like:
$.ajax({
url : 'ListMaker',
data: 'Q1',
success: function(data) {
//does something
}
});
This is what my python function looks like:
#app.route("/ListMaker",methods=["POST","GET"])
def ListMaker(text):
#make it a string just incase
quarter=str(text)
//do things with string
Any other similar questions I can find online, only talk about issues with Ajax and don't really cover the python side. In my case, the function is clearly being called, but it claims to receive no data to work with.
Am I sending the data wrongly from the Ajax side? Or am I parsing it wrongly on the python side?
Clarification for NoneType error from the comments below:
I am sending over:
data: JSON.stringify({"letter": "Q", "value": "25%"})
I am receiving it on the python side like so:
data=request.get_json()
letter=data["letter"]
value=data["value"]

The parameters in a Flask route are for variables in the path, called "variable rules" in Flask:
#app.route("/ListMaker/<text>", methods=["POST", "GET"])
def ListMaker(text):
...
As jQuery Ajax requests are GET by default, your data will be converted to a query string, in this case /ListMaker?Q1. You can access the query string in Flask with flask.request.args.
However, query strings are key-value, and you are only supplying a key, which will correspond to the Python dict {'Q1': ''}. You should either set the Ajax data to a string like quarter=Q1, or use an object:
$.ajax({
url : 'ListMaker',
data: {'quarter': 'Q1'}, // or 'quarter=Q1'
success: function(data) {
//does something
}
});
Then you will be able to access it in Flask:
#app.route("/ListMaker", methods=["POST", "GET"])
def ListMaker(): # no parameters needed
quarter = flask.request.args["quarter"]
# quarter == "Q1"
If you want to use a POST request, set method: 'POST' in the Ajax-call, and use flask.request.get_data() or flask.request.get_json() on the Flask side.

Related

How to write data to iframe via Flask POST method

I have an old application based on Python SimpleHTTPServer that I'm trying to convert to Flask.
In the old application, I had an HTML form that was submitting a POST request to the SimpleHTTPServer. The form also had an iframe. There, I had a do_POST method that was reading the values in the text boxes and producing some results. I then wrapped the results into a JSON object and wrote to the wfile method of SIMPLEHTTPServer. This caused the result to get populated into the iframe. The iframe had an onload method on the JS side and here, the results would be read from it and populated into various text-boxes.
I now want to convert this to Flask from SimpleHTTPServer. What is the best way to translate the logic I have in place to Flask? Basically, what is the equivalent of writing to the wfile object?
Also, on the Flask side, I also have some #app.route methods where I can form a URL with input parameters and get the results as JSON objects (example: http://localhost/calculate?input1=3&input2=5). Is it possible to leverage these URLs instead of the POST request to get the result into JavaScript?
Here is hello world of flask to get the data from URL parameters and do the stuff and return a json
from flask import Flask, jsonify, request
app = Flask(__name__)
#app.route('/')
def hello_world():
param1 = request.args.get('param1')
param2 = request.args.get('param2')
res = param1 + param2
return jsonify({
"result": res
})
if __name__ == '__main__':
app.run()
example request
GET http://127.0.0.1:5000/?param1=hi&param2=there
Example response
{
"result": "hithere"
}

How to access data passed into Flask with an AJAX call?

I am working on a project that displays hotel and airbnb data using flask and a sql database. We are trying to create a "favorite button" so the user can favorite/unfavorite listings. I've got an AJAX call to a Flask endpoint that will the make corresponding SQL queries to the "favorites" table. My problem is, I can't seem to access the data I'm passing into Flask.
Here is my AJAX call on the client-side:
function unfavoriteClicked(uid, itemid, type){
$.ajax({
type: "POST",
url: "/unfavorite",
data:{uid:uid, itemid:itemid, type:type},
contentType: 'application/json;charset=UTF-8',
success: function(data) {
console.log(data);
},
error: function(jqXHR) {
alert("error: " + jqXHR.status);
}
});
}
And here is my Flask code:
#app.route('/unfavorite', methods=["GET","POST"])
def unfavorite():
if request.method == "POST":
return request.form
return "this shouldn't happen"
Note that I've taken the SQL logic and other things out since I've figured out that I am not accessing the data correctly in Flask.
I am sure that the AJAX request goes through, because when I return something like "hello", it shows up in the console log. However, when I try to access the data dictionary I'm passing in, it returns a "500 internal server error" or some other kind of error depending on what I'm trying to access. I've tried to access a bunch of different things from looking at other stackoverflow posts (like request.form['data'], request.data, request.args, etc) but nothing seems to allow me to access the data. However, it does seem to allow me to access "request.method".
I was wondering if there is something fundamental that I am missing here that would be a reason why I cannot pass in data to Flask? Or any other suggestions for doing this "favorite" button are appreciated. Thanks!
So considering the main issue that you want to tackle is accessing the data that is been passed by your web page using Ajax. I have a solution which might work in your case.
So there are two parts in which i will explain how you can solve this problem.
1) Passing the data to your python controller/function to further process the data.
$.post("url_to_which_you_want_to_pass_data", {variable_name_to_access_in_python:any_value/variable_from_front_end},
function(response, status){
call_back_function_code
});
2) Accessing the data that has been passed from the webpage in python flask
#app.route('/unfavorite', methods=["GET","POST"])
def unfavourite:
if request.method == "POST":
any_variable_name = request.form.get("variable_name_to_access_in_python","")
print(any_variable_name) #If you want to print
return any_variable_name #If you want to see any_variable_name on web
return None
Hope it Helps! Cheers :)
I don't know if it's the best option, but its worked for me.
JavaScript:
var data = [1, 2, 3, 4]
var frontend_data = {'list':data}
$.ajax({
url: "/unfavorite",
contentType: 'application/json',
type: "POST",
data: JSON.stringify(frontend_data),
dataType: 'json',
success: function(result) {
console.log("Result:");
console.log(result);
}
});
Flask:
#app.post('/unfavorite')
def unfavorite():
data = request.get_json()
print(data['data']) #[1, 2, 3, 4]
return jsonify(data)

How to get all the data of an ajax data into django without using request.post

I want to get the data part of an ajax request into django as a dictionary without using request.post['name']
$.ajax({
url: "getAppointments",
method: "POST",
data: data, //I want to get this data as a dictionary in django
context: document.body,
}).done(function(data) {
alert("Successfully Edited");
}).fail(function(returnedText) {
window.alert("An error has occurred. Check log for details"+returnedText.responseText);
console.log(returnedText.responseText);
});
The client-size (your ajax request), and server-size (django) are two separate entities. Thus, you will have to parse the data coming into your getAppointments route like any other request body.
Regardless, request.POST in django is already a dictionary-like object: https://docs.djangoproject.com/en/2.1/ref/request-response/#querydict-objects
Stringify your JSON data and then receive it with json.loads() method in your Django view.
# Ajax
dataType: 'json',
data: {'my_dict': JSON.stringify(data)}
# views.py
my_dict = json.loads(request.POST.get('my_dict'))

Passing a string from Python to Javascript

I'm trying to pass a string from Python to Javascript via ajax POST request but i'm finding serious difficulties.
I've tried both with and without using JSON.
Here's the code
JAVASCRIPT
$.ajax({
url: url, #url of the python server and file
type: "POST",
data: {'data1': "hey"},
success: function (response) {
console.log(" response ----> "+JSON.parse(response));
console.log(" response no JSON ---> " +response);
},
error: function (xhr, errmsg, err) {
console.log("errmsg");
}
});
Python
import json
print "Access-Control-Allow-Origin: *";
if form.getvalue("data1") == "hey":
out = {'key': 'value', 'key2': 4}
print json.dumps(out)
Result is a empty JSON. when i do something like JSON.parse in javascript I get a unexpected end of input error, and when i try to get the length of the response data the size I get is 0.
I suppose that there should be some problems with the client server communication (I use a CGIHTTPServer) or maybe something wrong with the datatype that python or javascript expects.
I also tried without JSON, with something like
Python
print "heyyyyy"
Javascript
alert(response) //case of success
but I also got an empty string.
Could you please give me some advices for handling this problem ?
Thanks a lot!
You may want to compare the two snippets of code CGIHTTPRequestHandler run php or python script in python and http://uthcode.blogspot.com/2009/03/simple-cgihttpserver-and-client-in.html.
There isn't enough code to tell where your request handling code is but if it's in a class inheriting from CGIHTTPRequestHandler then you need to use self.wfile.write(json.dumps(out)), etc.
I managed to solve the problem using the method HTTPResponse from the Django Framework.
Now it's something very similar to this
PYTHON (answering the client with a JSON)
from django.http import HttpResponse
...
data = {}
data['key1'] = 'value1'
data['key2'] = 'value2'
.....
response = HttpResponse(json.dumps(data), content_type = "application/json")
print response;
JAVASCRIPT (Retireving and reading JSON)
success(response)
alert(JSON.stringify(response));
Or if I just want to send a String or an integer without JSON
PYTHON (no JSON)
response = HttpResponse("ayyyyy", content_type="text/plain")
print response
JAVASCRIPT (Retrieving String or value)
success: function (response) {
alert(response);
This works very good, and it's very readable and simple in my opinion!
Instead of print json.dumps(out) you should use return json.dumps(out)
The print will only display it in python's console, just as console in javascript.

Understanding how to use CGI and POST

I'm trying to understand how I can use Python and javascript so that I can use POST/GET commands. I have a button that sends a request to server-side python, and should return a value. I understand how to print out a response, but I want to pass a value to a javascript variable instead of just print thing the response.
For example, my javascript sends a string to the python file using the jquery POST function:
<script>
function send(){
$.ajax({
type: "POST",
url: "pythondb.py",
data:{username: 'william'},
async: false,
success: function(){
alert('response received')
},
dataType:'json'
});
}
</script>
Then using the python cgi module I can print out the value of username:
#!/usr/bin/env python
import cgi
print "Content-Type: text/html"
print
form = cgi.FieldStorage()
print form.getvalue("username")
however I am not receiving the data in the same way that the php echo function works. Is there an equivalent to 'echo' for the python cgi module?
I have read this question which explains the different python frameworks that can be used to communicate between browser and server; for the moment I was hoping to keep things as simple as possible and to use the cgi module, but I don't know if that is the best option.
Your success: function can take a parameter, to which jQuery will pass the contents of the response from the AJAX request. Try this and see what happens:
<script>
function send(){
$.ajax({
type: "POST",
url: "pythondb.py",
data:{username: 'william'},
async: false,
success: function(body){
alert('response received: ' + body);
},
dataType:'json'
});
}
</script>
P.S. Why are you using async: false? That kind of defeats most of the point of AJAX.
Your json is not in proper json format.
According to http://api.jquery.com/jquery.parsejson/,
username needs to be in quotes
you can only use double quotes
It would look like this:
{"username": "william"}
Also, your alert should have a semi colon on the end. I can't guarantee this answer will fix your problem, but it may be that your data isn't getting passed to cgi at all.

Categories

Resources