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

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)

Related

Using a URL as a URL parameter in Django Rest Framework

I have a model whose unique field is an address. The thing is, I am trying to get instances of this model using AJAX.
var address = 'http://example.com/blog/2/';
$.ajax({
url: 'http://sitemy.com/api/get_content/'+encodeURIComponent(address),
type: 'GET',
dataType: 'json',
success: function(json) {
console.log('Success');
}
});
In my urls.py, I have the following code:
url(r'^api/get_content/(?P<url>.+)/$', views.get_content),
So I am trying to use this URL pattern to capture the get request. However, I am constantly getting a 404 error since the url sent from the request does not match my pattern. What gives? How can I solve this?
In case its important, in my views, I am doing the following:
def get_content(request, address):
try:
content = Content.objects.get(address=urllib.unquote(address))
except:
return Response(status=status.HTTP_404_NOT_FOUND)
if request.method == 'GET':
serializer = ContentSerializer(content)
return Response(serializer.data)
Any help would be appreciated. Also, I welcome any general advice regarding the encoding of URLS, as that just boggles my mind for some reason. Thanks.

reload page after processing javascript output in flask

I have a javascript snipped which uses ajax to send an email address to my flask views.py script. I want to send a message to that address if the email is not in my database or otherwise reload the website and show the user information for that email address. Here is my javascript code which sends the data to my views.py
<script type='text/javascript'>
$(".send_invite_message").click(function(evt) {
var Toemail = document.getElementById('To').value
$.ajax({
url: "/send_invitation_member",
type: "GET",
async: true,
cache: false,
dataType: 'json',
contentType: "application/json; charset=utf-8",
data: { email: Toemail},
success: function(data) {
///do something
},
});
});
</script>
and in flask I would like to now have the option to send an email and if the email already exists in the database to reload the site
#app.route('/send_invitation_member', methods=['GET'])
def send_invitation_member():
if request.method == 'GET':
email = request.args.get('email')
search_result = check database for email entry
if search_result:
return render_template('show_members.html')
else:
send message and return json object
However the ajax script expects a json object back, so I don't know how to reload the site and show the user information. Is there any way to do this directly in flask or do I need to extend my javascript code and load the site from there?
thanks
carl
Since there's no way for an AJAX response to directly affect the page that's calling it, you'll need to extend your javascript a little (but only a bit).
In your success function, let's add the following:
success: function(data) {
if (data['url'] != null) document.location = data['url'];
else console.log('Got a valid JSON response, but no URL!');
}
This code will redirect the page to where the JSON specifies with its 'url' key. Now all that's left is to add it to our Flask code.
#app.route('/show_members')
def show_members():
return render_template('show_members.html')
#app.route('/somewhere_else')
def some_other_route():
return "It all works!"
#app.route('/send_invitation_member', methods=['GET'])
def send_invitation_member():
email = request.args.get('email')
search_result = check database for email entry
if search_result:
destination = url_for('.show_members')
else:
destination = url_for('.some_other_route')
send message and return json object
return Response(response=json.dumps({'url': destination}, mimetype='text/json')
I find when using flask it's better to separate your routes out into different functions depending on the HTTP method. And the url_for method? It's a life saver. You can find its docs here http://flask.pocoo.org/docs/0.10/api/#flask.url_for

AJAX not resolving url correctly

I have an HTML form that I want to submit to a flask endpoint, /add_int. When the form is submitted I intercept it with Jquery and submit the form to the endpoint using AJAX as follows:
var form = $( this ).serialize()
$.post({
url: "{{ url_for('add_int') }}",
data: JSON.stringify(form),
contentType: 'application/json;charset=UTF-8',
success: function(resp) {
console.log(resp);
}
});
The endpoint looks like this:
#app.route('/add_int', methods=['GET', 'POST'])
#login_required
def add_int():
# do stuff
return jsonify(status="success!")
My issue is that I never get to the endpoint.
When I examine my console I see
POST http://127.0.0.1:5000/[object%20Object] 404 (NOT FOUND)
instead of
POST http://127.0.0.1:5000/add_int
as I'd expect.
Note that if I set
url: '/add_int',
I run into the same problem.
I've found cases that use almost identical code that don't mention this problem:
e.g. how can I use data posted from ajax in flask?
My guess, is that my url is being resolved as a String object rather than a url, but I can't figure out why it's happening, and how to fix it.
What's going on?
You should remove the call to JSON.stringify, you can pass a serialized form directly as POST data and JSON.stringify is turning your object into [Object object].
url: '/add_int', isn't working because (it appears that) your frontend is running on a different port than the backend, so it will be rejected as a "cross domain" request. Have you inspected the value that "{{ url_for('add_int') }}" is returning?
Try not specifying the hash keys explicitly. http://api.jquery.com/jquery.post/
$.post("{{ url_for('add_int') }}",
JSON.stringify(form),
function(resp) {
console.log(resp);
},
'application/json;charset=UTF-8'
);

Url not being called through ajax

I'm trying to send some data to my django view through ajax. For some reason, the url is not being called. It always alerts "Not found!".
Here is my ajax code:
$.ajax({
url: "/AddToDb/",
type: "POST",
data: {"id":6,"quantity":3},
csrfmiddlewaretoken:'{{ csrf_token }}',
success: function(){
alert("Found!");
// code to update DOM here
},
error: function(xhr, ajaxOptions, thrownError){
alert("Not found!");
}
});
This is my url:
url(r'^AddToDb/$', 'Phase_2.views.AddToDb'),
And this is my view:
def AddToDb(request):
jdfsjfhs
if request.method == 'POST' and request.is_ajax():
JSONdata = request.POST['data']
dict = json.JSONDecoder().decode('JSONdata')
obj = ShoppingCart.objects.get(id=4)
obj.quantity = dict['quantity']
obj.save()
return render(request,"HTML.html")
It's just a dummy call to check whether i'm able to send data to my view or not. I'm a newbie so i'm sure i'm making a stupid mistake somewhere. Please help!
P.S The "jdfsjfhs" in my view is just to check whether the view is being called or not. It's not being called.
When making an ajax request. You need to send full url for instance localhost/AddToDb or www.example.com/AddToDb . You can check the final generated request from console section of either firefox or chrome. Hopefully that shall help.
use firebug to debug your javascript function. it will tell you whether the function is sending the correct response or not.

Can not get json response using $.getJSON

I am currently developing a Ruby on rails 3 application.
My server controller function render a json object as response:
class DaysController < BaseController
...
def the_days
...
render :json => days
end
end
In my javascript,I use the following code to get json response from server( that's from the_day function in controller)
$.getJSON(
url,
{emp_id: emp_id},
function(data) {
var result = data.response;
alert(result)
alert(data)
},
"json"
);
I use firefox browswer and checked with Firebug, in Firebug Net->XHR, I see the Get request is successful, and the response "days" is there. That's both request and response are successful.
But I did not see the two alert window defined in the above $.getJSON function, why? Why I can not get the response "days" in $.getJSON function??
-----------------Edited------------------
I edited my code to this one:
$.ajax({
url: myURL,
type: 'GET',
data: {
emp_id: emp_id
},
dataType: "json",
success: function(data) {
alert("hi");
alert(data)
}
});
When I run this code, the browser is stuck at success: function(data)
If data is coming back null, but the response was otherwise successful, I'd say that you're sending the request in a manner that violates the Same Origin Policy.
The request needs to be sent to the same host/port/protocol that served the original page.
If this is only an issue in your development environment, you can test in Chrome by launching it from a Terminal application with --disable-web-security.
EDIT: Try changing the parameter name from data to something else, like dat or whatever.
Then try an alert:
alert( dat );
I've heard of some browsers having trouble with the data parameter when you utilize the data property of an AJAX call.
I'm guessing that the problem is that data does not have a response property. Try alerting just the data variable. It should be the days object itself.
I wish I could just leave a comment but I guess I don't have access to that yet.
Anyway, I'd start with something even more basic. Add some text alerts just to make sure you're actually making it to where you think you are. ie...
$.getJSON(
url,
{emp_id: emp_id},
function(data) {
alert('hi') // add this
var result = data.response;
alert('bye') // add maybe even this
alert(result)
alert(data)
},
"json"
);
Sometimes when I'm debugging I find that even my most basic assumptions are wrong.
Edit: here's some sample code from working code I recently implemented
$.ajax({
url: 'users/check_username',
type: 'GET',
data: {
username: username
},
dataType: "json",
success: function(user_exists) {
alert(user_exists) // CHANGE THIS PART
}
});
It sounds like you are not sending the correct header in your ruby application. Firebug should report the response Content Type as application/json because that is what jquery is expecting it to be.
You could try changing the datatype in your ajax call to html to see if your alerts work with that, but that doesn't really help with the json parsing.
ALL, finally, I figured out the root cause. The reason is simply because of "Invalid json data" returned in server. That's in rails controller function 'def the_days':
render :json => days
should be modified to
render :json => days.to_json
Then, everything works smoothly:) Thank you all anyhow!

Categories

Resources