Jquery ajax POST inconsistent with Hapijs server inject - javascript

Here is what my Ajax post looks like:
$.ajax({
type: "POST",
url: "/create",
data: {
"question": $('#question').val(),
"options": options
},
success: function() { window.location.href="/view"; }
});
Fairly simple. options is an array of string charachters. The problem is, when I receive on the server end with Hapijs, the request payload shows this object received:
{
question: "..etc..",
"options[]": [..etc...]
}
Why does it add a [] to the options variable name? Normally this wouldn't be a problem for me, but when I do the same thing and simulate a server request in my lab test like this:
var test = [..etc..]
// Simulate POST request
var serverOptions = {
method: 'POST',
url: '/create',
payload: {
question: 'Question',
options: test
}
};
It shows that the variable name received is just "options", not "options[]". How can I get jquery to stop adding the [] to the variable name when POSTing? Thanks

Related

jQuery .ajax() - add query parameters to POST request?

To add query parameters to a url using jQuery AJAX, you do this:
$.ajax({
url: 'www.some.url',
method: 'GET',
data: {
param1: 'val1'
}
)}
Which results in a url like www.some.url?param1=val1
How do I do the same when the method is POST? When that is the case, data no longer gets appended as query parameters - it instead makes up the body of the request.
I know that I could manually append the params to the url manually before the ajax request, but I just have this nagging feeling that I'm missing some obvious way to do this that is shorter than the ~5 lines I'll need to execute before the ajax call.
jQuery.param() allows you to serialize the properties of an object as a query string, which you could append to the URL yourself:
$.ajax({
url: 'http://www.example.com?' + $.param({ paramInQuery: 1 }),
method: 'POST',
data: {
paramInBody: 2
}
});
Thank you #Ates Goral for the jQuery.ajaxPrefilter() tip. My problem was I could not change the url because it was bound to kendoGrid and the backend web API didn't support kendoGrid's server paging options (i.e. page, pageSize, skip and take). Furthermore, the backend paging options had to be query parameters of a different name. So had to put a property in data to trigger the prefiltering.
var grid = $('#grid').kendoGrid({
// options here...
dataSource: {
transport: {
read: {
url: url,
contentType: 'application/json',
dataType: 'json',
type: httpRequestType,
beforeSend: authentication.beforeSend,
data: function(data) {
// added preFilterMe property
if (httpRequestType === 'POST') {
return {
preFilterMe: true,
parameters: parameters,
page: data.page,
itemsPerPage: data.pageSize,
};
}
return {
page: data.page,
itemsPerPage: data.pageSize,
};
},
},
},
},
});
As you can see, the transport.read options are the same options for jQuery.ajax(). And in the prefiltering bit:
$.ajaxPrefilter(function(options, originalOptions, xhr) {
// only mess with POST request as GET requests automatically
// put the data as query parameters
if (originalOptions.type === 'POST' && originalOptions.data.preFilterMe) {
options.url = options.url + '?page=' + originalOptions.data.page
+ '&itemsPerPage=' + originalOptions.data.itemsPerPage;
if (originalOptions.data.parameters.length > 0) {
options.data = JSON.stringify(originalOptions.data.parameters);
}
}
});

AJAX request cannot pass DateTime to server if using GET method

I have a form which uses Kendo controls, and when user click the button, an AJAX request gathering these controls' value will be sent to server and download a file based on these criteria. One of the controls is DateTimePicker.
$.ajax({
type: 'POST',
contentType: "application/json; charset=utf-8",
url: '#Url.Action("MyGenerateReportMethod")',
async: true,
data: getViewModel(),
...
});
function getViewModel() {
...
viewModel.DateFrom = $("#DateRangeFrom").data("kendoDatePicker").value();
...
return JSON.stringify({ para: viewModel });
}
public ActionResult MyGenerateReportMethod(MyModel para)
{
try{
...
}
}
public class MyModel
{
public DateTime? DateFrom { get; set; }
}
The above simplified code demonstrate my situation.
I have a POST ajax request to server, which passes a serialized JSON object including a Kendo DateTimePicker Value.
The server side action try to catch this JSON object as parameter and do the stuff which is irrelevant to this question.
My question is, for some reason I have to changed the request from POST to GET.
While it works using POST method, it does not work if I change "POST" to "GET".
I checked the request sent in Chrome's Developer Tools, It does sent the JSON object in the following format: (In Query String Parameters section in the Network Tab)
{"para": {
...
"DateFrom":"2016-04-13T16:00:00.000Z"
...
}
}
However, at server side, MyModel para does not seems to catch this object successfully (if I change from "POST" to "GET"). Other fields still can be bound while all DateTime fields become null.
Why is this happening, and how can I change the request from "POST" to "GET"?
Thanks.
EDITED
Based on some comments / answers, I have tried to modified the AJAX request to the following code, but it is still not working... (Same behavior)
$.ajax({
type: 'GET',
url: '#Url.Action("SumbitOutstandingReportList")',
data: getPlanViewModel(),
async: true,
...
}
function getPlanViewModel(){
var obj = {};
...
obj.DateFrom = $("#DateRangeFrom").data("kendoDatePicker").value();
...
return { para: obj };
}
A GET does not have a body, so remove the contentType: "application/json; charset=utf-8", option (does no harm but its only applicable to a POST) and adjust the data so that the ajax call is
$.ajax({
type: 'Get',
url: '#Url.Action("MyGenerateReportMethod")',
data: getViewModel(),
...
});
function getViewModel() {
var obj = {};
...
obj.DateFrom = $("#DateRangeFrom").data("kendoDatePicker").value();
...
return obj; // return the object, not a stringified object containing another object
}
Note this assumes the value is in a format that matches your server culture, or in ISO format (e.g. the request will be DateFrom: '2016-04-13T16:00:00.000Z')
This is happening because of, GET method is pass data in a header or url, while json data can not passed through header, change the method of passing data, which is currently in a json format.
You could do like even :
var fd = new FormData();
fd.append('data', yourData);
and send fd as a directly data object, it will work.
GET request has no body, it passes the parameters in either cookies or URL query string, so pass the data you want in a query string parameter like below:
var url = #Url.Action("MyGenerateReportMethod",new {DateFrom="_X_"});
url = url.replace("_X_",$("#DateRangeFrom").data("kendoDatePicker").value());
$.ajax({
type: 'GET',
url: url,
async: true
});

Sending a JSON object to Django backend through AJAX call

I have the following code (jQuery) to create a json file:
$( ".save" ).on("click", function(){
var items=[];
$("tr.data").each(function() {
var item = {
item.Code : $(this).find('td:nth-child(1) span').html(),
itemQuantity : $(this).find('td:nth-child(4) span').html()
};
items.push(item);
});
});
Now this is my AJAX function:
(function() {
$.ajax({
url : "",
type: "POST",
data:{ //I need my items object, how do I send it to backend server (django)??
calltype:'save'},
dataType: "application/json", // datatype being sent
success : function(jsondata) {
//do something
},
error : function() {
//do something
}
});
}());
Now, my doubt is how do I send the 'item[]' object that I created to the backend? I do need to send both the item[] object and the variable 'calltype' which signals what made the AJAX call, as I have the same Django View (its the Controller equivalent for Django) in the backend being called by different AJAX functions.
How will my AJAX function look like?
Hey guys just got my answer right.
I used the following ajax function to get it right:
(function() {
$.ajax({
url : "",
type: "POST",
data:{ bill_details: items,
calltype: 'save',
'csrfmiddlewaretoken': csrf_token},
dataType: 'json',
// handle a successful response
success : function(jsondata) {
console.log(jsondata); // log the returned json to the console
alert(jsondata['name']);
},
// handle a non-successful response
error : function() {
console.log("Error"); // provide a bit more info about the error to the console
}
});
}());
So, this is sort of a self answer!!! :) Thanks a lot SO!!

How to add text to the body of a CasperJS thenOpen() POST request

I need to write a script inside of datorama.com to access pardot.com. Pardot does have an API that requires a request that has a request inside the body as
POST: https://pi.pardot.com/api/login/version/3
message body: email=&password=&user_key=
Right now here is my code:
phantom.casperPath = casperPath;
phantom.injectJs(casperPath + "/bin/bootstrap.js");
var casper = require('casper').create({
verbose: true,
logLevel: 'debug'
});
casper.start().thenOpen('https://pi.pardot.com/api/login/version/3',{
method: 'post',
content: {
'text' : 'email=<myemail>&password=<password>&user_key=<userKey>'
}
}, function(response) {
this.echo(this.getHTML());
});
casper.run();
I can tell that it is getting through to the server because it is responding this.echo(this.getHTML()); "Login Failed" . I am using the right email/password/user_Key because i am pulling that from the API Console for pardot and it is working there.... So I believe the issue is I am not setting the body of the request correctly.
So does anyone know a way to set the body on the request?
casper.open() or casper.thenOpen() don't understand the content setting. You probably wanted to use data:
casper.start()
.thenOpen('https://pi.pardot.com/api/login/version/3', {
method: 'post',
data: 'email=<myemail>&password=<password>&user_key=<userKey>'
}, function() { ... });
Don't forget to use encodeURIComponent() on the email, password and user key parameters if you build the string yourself.
You can also pass an object:
casper.start()
.thenOpen('https://pi.pardot.com/api/login/version/3', {
method: 'post',
data: {
email: '<myemail>',
password: '<password>',
user_key: '<userKey>'
}
}, function() { ... });
If you expect something else than HTML from the API, then you should use casper.getPageContent() instead of casper.getHTML().

Jquery ajax post to MVC2 action

I'm using the following script to post to and endpoint, it's hitting the breakpoint on the server so I know the routing is correct.
$(document).ready(function() {
var o = new Object();
o.message = 'Hi from the page';
$.ajax({
type: 'POST',
contentType: 'application/json;',
data: JSON.stringify(o),
dataType: 'json',
url: 'home/PingBack',
success: function(result) {
alert(result.success);
}
});
});
The endpoint on the server looks like this.
public JsonResult PingBack(MHolder message)
{
return Json(new { success = "steve"});
}
and the Model looks like this.
public class MHolder
{
public string message { get; set; }
}
I'm sure that in the past the values have been automatically bound to the model, but I can't seem to get anything to be bound atm! Even if I just pass the value as a string, I'm sure it's something silly that I'm missing any ideas?
A few things to notice. You are sending the request as a JSON string (contentType: 'application/json' and JSON.stringify(o)) while on the server you are expecting an object of type MHolder. The default model binder won't do this transformation. You will need to either write a custom model binder capable of deserializing JSON back to an MHolder instance or send the request as key=value pairs (do not stringify):
var o = new Object();
o.message = 'Hi from the page';
$.ajax({
type: 'POST',
data: o,
dataType: 'json',
url: 'home/PingBack',
success: function (result) {
alert(result.success);
}
});
The code seems OK to me, at first glance.
try using...
data : {message : "Hi from the page."},
...to see if this causes the MHolder instance to be populated.
Also, use something like Fiddler to capture your requests and allow you to see exactly what is being posted.

Categories

Resources