Passing a string from Python to Javascript - 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.

Related

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

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.

How to convert ajax json post request from Jquery to Python/Django dictionary

I am trying to convert an AJAX request retrieving JSON from JS to Python's dictionary in Django, but unsuccessfully. Please help.
This is the original JS code:
myJSON = JSON.stringify(myJsObject);
// POST - send JSON data to Python/Django server
$.ajax({
url: "/savemyexposuresituation",
type: "POST",
datatype: 'json',
data: myJSON,
async: false,
success: function() {
alert('Your data is saved :)');
},
error: function() {
alert('Error occured :(');
}
});
}
This is the Django side:
def saveExposureSituation(request):
#get es data - JSON file
fromJs = request.POST
fromJs = json.loads(fromJs)
All I get is JSON object must be string, not QueryDict. I tried to convert this QueryDict to something else unsuccessfully.
In python 3 to convert byte to strings you need to use decode("utf-8"). So may be to something like this request.POST.decode("utf-8")
request.POST is for form-encoded data. You should be using request.body.
Thanks to responses, the complete answer would be:
def saveExposureSituation(request):
fromJs = request.body
fromJs = fromJs.encode('utf-8')
#now we can load our JSON from JS
fromJs = json.loads(fromJs)

JSON response from Python json.dumps

I am trying to send a Django HttpResponse encoded as JSON to Javascript.
Python:
response_data = {}
response_data['status'] = 'incomplete'
return HttpResponse(json.dumps(response_data), content_type="application/json")
Jquery:
function auth_request(){
$.ajax({
url: AUTH_ENDPOINT + "myid0001",
context: document.body,
success: function(response){
console.log(response);
console.log(response.status);
if(response.status == "incomplete"){
//do something here
}
}
}
});
}
The console prints {"status": "incomplete"} for the first console log and undefined for the console.log function accessing the status element.
I tried using JSON.parse(response) but I get the error
Uncaught SyntaxError: Unexpected token a in the jquery.js file which I believe is indicating that the object is already a JSON object. However, if I check the type of the object, it displays string. How can I access the elements of the response JSON object?
You need to parse the Json back into a JS object when it's received. Otherwise, it's just text.
jQuery will do that for you if you specify dataType: "json" in the Ajax call.
I found the solution. It turns out that my Django setup was returning some additional string items so when I tried to set dataType: "json" (as #Daniel Roseman suggested) or in the jQuery function or use JSON.parse(response) I received an error. I was able to remove the extra string and it worked properly.

Sending JSON as a parameter value for post

Here's what I'm trying to accomplish:
User enters JSON in a textarea element.
{
"test":[
{"a":"b"}
]
}
Client side JavaScript parses the JSON.
myObject = $.parseJSON($("#my-textarea").val());
JSON is sent over an ajax post request to the server with
dataType: json,
data: {"my_object": myObject}
Post parameters are checked on the server side in sinatra and the JSON looks like this now.
{
"test": {
"0": {
"a": "b"
}
}
}
I'm wondering why the test array was changed into a hash and if there's anything I can do to avoid that. I'm thinking that the original JSON is improperly formatted, but I'm unsure.
EDIT:
Here is a stripped down version of the ajax request and controller action.
function test() {
return $.ajax({
url: "/test",
type: "post",
dataType: "json",
data: {"test":[{"a":"b"}]},
success: function(response) {
}, error:function(jqXHR,exception) {
ajaxError(jqXHR,exception);
}
})
}
post '/test' do
puts params
return {}
end
I would stringify the resulting JSON object before you send it, like this:
dataType: json,
data: {"my_object": JSON.stringify(myObject)}
If you have to support browsers that don't have JSON natively, you can conditionally import the json js to add that support. (jQuery does not natively have a JSON stringify method).
Try this
var test = "{ \"test\":[{\"a\":\"b\"}]}"
$.parseJSON(test) // or even JSON.parse(test)
If you trace the object before it goes to the server side you will confirm that it was parsed correctly. So the problem is in sinatra I would say.
Just first check what's the parse result before doing the server call.
If you don't know if it's your client doing the bad translation, create a native javascript object (without the parse) and send it instead. If it's still bad, I doubt the problem is on the client.
Output I got on the chrome console:
JSON.parse(test)
Object {test: Array[1]}
test: Array[1]
0: Object

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