How to retrieve json data from a post request in Pyramid? - request

In Pyramid:
class ProjectorViews(Layouts):
def __init__(self, request):
self.request = request
#view_config(renderer="json", name="updates.json", request_method="POST")
def updates_view(self):
print self.request.params
JS:
$(function() {
function get_updates () {
data = JSON.stringify({'a':1});
$.post('/updates.json', data, function(res) {
});
}, 'json').done(function() {
});
}
get_updates();
});
The console shows self.request.params returns NestedMultiDict([('{"a":1}', u'')])
How do I get the keys and values in the NestedMultiDict object?
If I do self.request.params.getall("a"), it reports
KeyError: "Key not found: 'a'"
And if I do self.request.json_body, it reports
ValueError: No JSON object could be decoded

$.post() always sends data with application/x-www-form-urlencoded content type. Use $.ajax() to send the data with correct content type:
$.ajax({
url: url,
type: "POST",
data: data,
contentType: "application/json; charset=utf-8",
dataType: "json"
}).done(...);
On the Pyramid side request.json_body is the correct way to access... well, JSON body of the request.

Related

Sending an array of integer values via AJAX post to Flask view

Suppose you have an array in javascript - [1,2,3] and you want to send it via AJAX post to Flask.
So that in JS:
array = new Array()
array.push(1);
array.push(2);
array.push(3);
var data = JSON.stringify(array);
$.ajax({
type: "POST",
url: "myurl",
data: data,
dataType: 'JSON',
success: alert("messagesent!")
})
And in Flask view :
#bp.route('myurl',methods=['GET', 'POST'])
def myfunction(address):
if request.method == "POST":
FirstSet = request.form['data']
x = json.loads(FirstSet)
However now I dont know how to access the particular values of x list(?), because trying to access it like this :
print(x[1])
does not work...Thanks in advance for looking at it :)
EDIT:
The bigger picture:
I trigger ajax request onclick but after I append all the values that I want to to the array that i want to send. It looks like this:
$("#firstSet").on("click",function(){
array =[]
$("#myDiv").children().each(function()
{
var star = $(this).children("li.star.selected").length
array.push(star)
})
alert(array)
$.ajax({
type: "POST",
url: "myurl",
data: {"data":array},
success: alert("messagesent!")
})
})
This alerted array is not NoneType (and I just get my array values) but what I receive in Flask side is an empty list or NoneType (depenending on how i request it)
Since you're sending JSON you should use Flask to get that JSON with the appropriately named .get_json():
# ...
FirstSet = request.get_json()
Then FirstSet will contain:
[1, 2, 3]
Also ensure your AJAX has the appropriate contentType:
// ...
contentType: "application/json",
dataType: "JSON"
Edit: I'm including all the Javascript/JQuery that I'm testing with in case it helps you. I wrapped everything in a DOM ready function.
<script>
$(document).ready(function() {
$("#firstSet").on("click",function(){
array = [];
var listItems = $("#myDiv li");
listItems.each(function(idx, li) {
var star = $(li);
array.push(star.length);
});
alert(array);
$.ajax({
type: "POST",
url: "/testing",
contentType: "application/json",
dataType: "JSON",
data: JSON.stringify(array)
});
});
});
</script>
And the HTML:
<button id="firstSet" name="firstSet">testing</button>
<div id="myDiv" name="myDiv">
<ul id="myList">
<li data-value="1">1</li>
<li data-value="2">2</li>
<li data-value="3">3</li>
</ul>
<input id="listChoice" size="15" name="size" type="text" />
</div>
And the Flask code:
#bp.route('/testing',methods=["GET","POST",])
def testing():
if request.method == "POST":
print(request.get_json())
return render_template('testing.txt')

angular POST not working with servlet

I am trying to use angularjs POST (or even GET) to a servlet with the following:
var json = { hello: "world" }
var deffered = $q.defer();
$http({
method: "POST",
url: url,
headers: { "Content-Type" : "application/json" },
request: JSON.stringify(json)
}).then(data) {
if(data.data) {
deferred.resolve({
response : data
});
)
})
return deffered.promise;
within the servlet, simple:
String val = request.getParameter("request")
it never seems to see it
I have tried:
data: JSON.stringify({ request: json })
data: { request: json }
"request" : JSON.stringify(json)
etc
if I comment out the getParameter and just return a generic value using Gson
JsonObject json = new JsonObject();
json.addProperty("This", "works");
response.getWriter().print(new Gson().toJson(json));
that comes back fine so is there something within the angular POST I am doing wrong here? I have also tried using "GET" instead but same result.
EDIT: I would like to understand POST method and the "proper" way to get the data from the json object if getParameter is wrong please~
getParameter() returns http request parameters, you should add this params by using :
params: JSON.stringify(json)
Not with
request: JSON.stringify(json)
Take a look in params in get and params in post.

Is it not possible to send an array with GET method?

On the server side I have a method that accepts an array of integers and returns a Json object:
public JsonResult GetCorrespondingOfficers(int[] categories){
//use `categories`
return Json(model,JsonRequestBehavior.AllowGet);
}
And I have the following script on the client:
var categories=[1,2,3];
$.ajax({
url: url,
type: 'GET',
data: { categories: categories },
contentType: 'application/json; charset=UTF-8',
dataType: 'json',
success: function (data) { alert('Success');},
async: false
});
When I run the above code I get null for the parameter categories on the server side. If I change the method from GET to POST, then it works. Does it mean that I can't send an array or any Json data with GET request? If not, then what's the problem with my code?
You can send array as a string:
...
data: { categories: JSON.stringify(categories) },
...
GET request does not have message body, so you can't use GET with contentType: 'application/json; charset=UTF-8'. When you use json in GET request, browser breaks your json and append each josn key value to the url(even if you use JSON.stringify method). Therefore for using json and REST you need to use POST method.

Sending json array as querystring in senchatouch2

Should we send json array or normal array as querystring in senchatouch2
in any case you can only send String in URL so if you have JSON then use Ext.JSON.encode to make it string and if you have JS Array use toString or join method to flatten the array before appending it to URL.
Since you said querystring so I suppose you and not doing POST request.
[EDIT]
Looking at your comment it seems you want to send some data to service for creation but in that case you should not send data as querystring, you should send it in message body. Following is example to send JSON data to your service:
var obj = new Object();
obj.loginEntry = new Object();
obj.loginEntry.userid = username;
obj.loginEntry.password = password;
var data = Ext.JSON.encode(obj);
Ext.Ajax.request({
url : 'http://myserver:port/service/entity',
method : "POST",
headers: {
/* Important because default is
* Content-Type:application/x-www-form-urlencoded; charset=UTF-8
* which is not supported by service
*/
'Content-Type': 'application/json'
},
params : data,
success : function(response) {
},
failure : function(response) {
}
}
);
[/EDIT]
While we use POST method to send parameters in Sencha Touch2 use jsonData in Ajax Request like,
Ext.Ajax.request({
url:'',
method:'POST',
disableCaching:false,
headers: {
'Accept':'application/json',
'Content-Type':'application/json'
},
jsonData: {
FirstName:fname //{"FirstName":["Sam","paul"]}
},
success: function(response)
{
console.log(response.responseText);
},
failure: function(response)
{
console.log(response.responseText);
},
});

backbone.js error when using fetch but not $.ajax()

I am having some trouble fetching a collection. I'm using the console's network inspector to see if I can figure out what's wrong and the only thing I see is the format of the Request Payload.
When making a .fetch() the Request Payload is being sent in this format:
query=this+is+my+query
This returns a 400 Bad Request status from my server. I have tested using:
$.ajax({
contentType: 'application/json',
async : false,
type:'POST',
url: '/search',
data: JSON.stringify({"query":"this is my query"}),
dataType: 'json',
success: function(data) {
alert('yup');
},
error: function(data) {
alert('nope');
}});
which returns my data as expected. In this case the Request Payload is in this format:
{"query":"enterprise search is gonna rock","scope":null}
I've tried passing in headers with my fetch:
my_results.fetch({data:{"query":"this is my query"}, type: 'POST', dataType: 'json', contentType: 'application/json'});
Here is what my Model and Collection look like:
EnterpriseSearch.Result = Backbone.Model.extend();
EnterpriseSearch.Results = Backbone.Collection.extend({
model: EnterpriseSearch.Result,
url: "/search"
});
Any help would be appreciated.
Try using data: JSON.stringify({"query":"this is my query"}) in your fetch options, just like you do when using $.ajax. jQuery will default to application/x-www-form-urlencoded for form data.

Resources