Passing variables between Python and Javascript - javascript

Imagine that you need to write some Javascript that simply changes a set of checkboxes when a drop down list is changed.
Depending on which item is selected in the list, some of the checkboxes will become checked/unchecked.
In the back, you have Python code along with some SQLAlchemy.
The Javascript needs to identify the selected item in the list as usual, send it back to the Python module which will then use the variable in some SQLAlchemy to return a list of checkboxes which need to be checked i.e. "User selected 'Ford', so checkboxes 'Focus', 'Mondeo', 'Fiesta' need to be checked"
The issue Im having is that I cant seem to find a way to access the python modules from the Javascript without turning a div into a mini browser page and passing a url containing variables into it!
Does anyone have any ideas on how this should work?

Funny, I've got web pages with JavaScript that talk to Python CGI modules that use SQLAlchemy.
What I do is send AJAX request but with JSON request in the body instead of XML. Python CGI modules use standard json module to deserialize JSON into a dictionary.
JavaScript side looks like this:
function on_request_success(response) {
console.debug('response', response);
}
function on_request_error(r, text_status, error_thrown) {
console.debug('error', text_status + ", " + error_thrown + ":\n" + r.responseText);
}
var request = { ... };
jQuery.ajax({
url: 'http://host/whatever.cgi',
type: 'POST',
cache: false,
data: JSON.stringify(request),
contentType: 'application/json',
processData: false,
success: on_request_success,
error: on_request_error
});
And Python like this:
request = json.load(sys.stdin)
response = handle_request(request)
print("Content-Type: application/json", end="\n\n")
json.dump(response, sys.stdout, indent=2)
Note, it doesn't use Python cgi module, since the whole request is passed as JSON in the body.

python has a json module, which is a perfect fit for this scenario.
using a good old AJAX, with json as the data format will allow you to exchange data between javascript and your python module.
(unless your python module is running on the client side, but then i don't see how you could execute it from the browser...)

Ajax is a good way to pass variables between python and javascript.
Javascript:
param = {a:'hello', b: 'world', c: '!'}
$.ajax({
type: "post",
url: "scpi.py",
cache: false,
async: 'asynchronous',
dataType: 'html',
data: param,
success: function(data) {
console.log(data)
},
error: function(request, status, error){
console.log("Error: " + error)
}
})
Server.py: (You will need a three functions for this to work)
def do_POST(self):
if "scpi.py" in self.path:
form = cgi.FieldStorage(
fp=self.rfile,
headers=self.headers,
environ={'REQUEST_METHOD': 'POST'}
)
a = form['a'].value
b = form['b'].value
c = form['c'].value
content = myfunction(a, b, c)
self.respond(content)
def handle_http(self, data):
self.send_response(200)
self.send_header('Content-type', 'application/json')
self.end_headers()
print(data)
return bytes(str(data), 'UTF-8')
def respond(self, data):
response = self.handle_http(data)
print(data)
FYI: "myfunction(a, b, c,)" is a function from another python file, then return the data and passes to self.respond to send back to javascript

Related

Can I query the neo4j database with Javascript?

I have created a geohash neo4j database for NYC Taxi data.
Now the next step is to visualize it within a map, for that i choosed Leaflet as a Javascript library.
with static data i can plot geohash data in Leaflet:
but now i want to query that data from the neo4j database and render it.
so is it possible to do that or only with a server side scripting language(node.js,php...) ?
Update
i found a simlair question here , the solution is to query the database with ajax however it dosen't work for me and i get "error" in the console:
var body = JSON.stringify({
statements: [{
statement: 'MATCH (n) RETURN count(n)'
}]
});
$.ajax({
url: "http://localhost:7474",
type: "POST",
data: body,
contentType: "application/json"
})
.done(function(result){
console.log(result);
})
.fail(function(error){
console.log(error.statusText);
});
It's possible to query Neo4j from client-side Javascript with Neo4j Driver for JavaScript.
I have used this in a couple of projects.
You can either download the driver and include in your HTML file like:
<script src="lib/browser/neo4j-web.min.js"></script>
Or just use the CDN link like:
<script src="https://unpkg.com/neo4j-driver#X.Y.Z/lib/browser/neo4j-web.min.js"></script>
I find the solution:
first the url for the database is : "http://localhost:7474/db/data/transaction/commit" and not "http://localhost:7474".
then after changing that i got an unauthorized error in console , that means i need to add my user/password to my ajax call, this is done by a function called beforeSend like this:
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Basic " + btoa("neo4j"+ ":" + "your_neo4j_password"));
}}
so the final Ajax Solution is :
$.ajax({
url: "http://localhost:7474/db/data/transaction/commit",
type: "POST",
data: body,
contentType: "application/json",
beforeSend: function (xhr) {
xhr.setRequestHeader ("Authorization", "Basic " + btoa("neo4j"+ ":" + "password"));
}}
)
.done(function(result){
console.log(result);
})
.fail(function(error){
console.log(error.statusText);
});
Rajendra Kadam's answer is correct.
First you need to install neo4j-driver by:
npm install neo4j-driver
in a directory probably one level higher than the web/ directory of your node.js server.
Then you need to put the neo4j-web.min.js into the web/ directory, where your client-side JavaScript can load.
Then you add the line in your HTML:
<script src="js/neo4j-web.min.js"></script>
The file neo4j-web.min.js is located in node_modules/neo4j-driver/lib/browser/.
Then in your client-side JavaScript, put:
var driver = neo4j.driver(
'neo4j://localhost',
neo4j.auth.basic('neo4j', 'password') );
Then you have successfully opened the driver. (You may need to set your password correctly or you'll get an authentication error.)
Note that you DON'T need this line on your client-side JavaScript:
var neo4j = require('neo4j-driver');
because it is for server-side node.js.

Passing a list data from html to python (flask)

I passed a list data selectedOrder from python to html as below.
return render_template(f"fillForm.html", items=selectedOrder)
I know there is a way to send a single data from html either by using input form or appending data to url as in /fillForm?sid=3&quantity=5 but I'm curious if I can send a list data from html back to python in such a manner as well. Obviously I can just store the data to some variable within python before passing it but given how my code is working, it would be better to directly get the data from html if possible. Not sure if this will matter, but I use flask and jinja2 template.
You could use an ajax request and send your list as a json. Flask provides the method request.get_json() to retrieve the json data received as a dict. Assuming you have jquery it would be like:
$.ajax({
url: "/your_route",
type: "POST",
contentType: "application/json;charset=UTF-8",
dataType: "json",
data: JSON.stringify({html_data: yourlist}),
success: function(response) {
console.log(response);
},
});
Then on flask side:
#app.route('/your_route')
def your_route():
data = request.get_json()
print(data['html_data']) # should print your list
# don't forget to return a success status

Jquery ajax success response is string not javascript object

I'm making a jQuery AJAX call to my Rails app (all run on localhost) which is responding with Javascript. The javascript is running because I'm getting the alert. But, I would like to read the my_var variable in the js.erb file. However, when I try to look at the data parameter of the success function it sees the data as a string. So doing data.my_var is undefined.
js.erb file
var my_var = "hi";
alert('this ran');
javascript
$.ajax({
url: "/a/validate?a_id=" + "<%= params[:id] %>",
context: this,
dataType: "script",
data:
{
json_a: JSON.stringify(this.a),
model_to_validate: model,
target_class: target_class,
current_class: current_class
},
success: function (data, textStatus, jqXHR) {
if(!this.orderFormViewed) {
this.orderFormViewed = data.order_block_opened;
}
},
error: function (data) {
console.log("error in ajax validate call");
debugger;
}
})
That's because that's exactly what you told it to do with dataType: "script" - look at the dataType options below. The script is run in it's own context and so you won't see that variable (I believe). You're going to need to communicate differently if you want that set. Or if you just need data send json.
https://api.jquery.com/jQuery.ajax/
"script": Evaluates the response as JavaScript and returns it as plain text. Disables caching by appending a query string parameter, "_=[TIMESTAMP]", to the URL unless the cache option is set to true. Note: This will turn POSTs into GETs for remote-domain requests.
try to change your dataType to json if you only need to get an object and be sure your server return a json.

AJAX/JSON in server-side: pass all arguments to a Python dictionary (Flask)

I have a jQuery AJAX call in my Javascript that sends a lot of information to the server:
(Javascript)
$.ajax({
datatype: "json",
url: SCRIPT_ROOT + '/email',
data: $.extend({}, dict_list[0], dict_list[1]),
success: (function(){console.log('E-mail success.')}),
error: (function(){console.log('E-mail failure.')})
})
Right now I'm just putting all the dictionary keys into a list and creating the dictionary like that:
(Python)
def testemail():
"""
pre = ['red', 'blu', 'red_t', 'blu_t', 'red_p', 'blu_p', 'n_r', 'tou', 'mo', 'comm']
post = [''] * len(prestats)
for i in range(0, len(prestats)):
post[i] = request.args.get(pre[i], '', type = str)
Is there a way, in my Flask Python server-side code, to automatically parse all that data into a dictionary? Basically I want something to take all the arguments that the $.ajax created and recreate a dictionary in Python.
Could you be looking for request.json?

AJAX Post to store JSON with Python and javascript

I have been having problems with getting AJAX to post JSON correctly. The application is intended to be hosted on Google App Engine. But what I have does not post data.
Python
mainPage = """
<html>
html is included in my python file.
</html>
"""
class JSONInterface(webapp2.RequestHandler):
def post(self):
name =self.request.get('name')
nickname =self.request.get('nickname')
callback = self.request.get('callback')
if len(name) > 0 and len(nickname) >0:
newmsg = Entry(name=name, nickname=nickname)
newmsg.put()
if len(name)>0:
self.response.out.write(getJSONMessages(callback))
else:
self.response.out.write("something didnt work")
def get(self):
callback = self.request.get('callback')
self.response.out.write(getJSONMessages(callback))
This handler is meant to handle the Ajax calls from the web app. I am unsure if I need javascript to be associated with my main page in order to do so, as I haven't found information on it yet with my searches.
Javascript
$(document).ready( function() {
$("#post").bind('click', function(event){
var name = $("#name").val();
var nickname = $("#nickname").val();
postData = {name: name, nickname: nickname, callback: "newMessage"};
$.ajax({
type: "POST",
url: "http://localhost:27080/json",
data: postData,
dataType: "json",
done: function() {
// Clear out the posted message...
$("#nickname").val('');
},
fail: function(e) {
confirm("Error", e.message);
}
});
// prevent default posting of form (since we're making an Ajax call)...
event.preventDefault();
});
The Javascript for the post
Can someone advise me on how I could resolve the problem I am having. Thanks for the time and help.
Did you ask the same question yesterday and then delete it? I swear I just answered the same question.
You're not sending your data as a JSON string. If you want to send as JSON, you need to encode data as a JSON string, or else you're just sending it as a query string.
data: JSON.stringify(postdata),
HOWERVER, your request handler is actually processing the request properly as query string instead of JSON, so you probably don't want to do that.
For starters, the ajax call is pretty close. The full path
"http:://localhost:27080/json"
is not necessary, the relative path will work, but that is not the problem.
Your callback, as it stands, will work as 'success':
success: function(response) {
alert(response);
// Clear out the posted message...
$("#nickname").val('');
}
However, this callback is being phased out in favor of other methods. 'Done' should be chained like so:
$.ajax({
type: "POST",
url: "/json",
data: postData,
dataType: "json"
}).done(function(data){
console.log(data);
});
Also, there might be problems on the server. If you use some logging, you will see that the data is indeed being sent to the server.
import json ## we'll get to this below
import logging
class JSONInterface(webapp2.RequestHandler):
def post(self):
name = self.request.get('name')
logging.info(name) ## will print the value of 'name'
Unless your python function getJSONMessages(callback) is returning a json object, your callback will not be called, even after you add the response parameter.
In your python code:
import json
import logging
class JSONInterface(webapp2.RequestHandler):
def post(self):
callback = self.request.get('callback')
logging.info(callback) # will print correctly
self.response.out.write(json.dumps(callback))
Using the json.dumps method encodes the passing object to json, which is what your ajax object is looking for.

Categories