Posting JSON with AJAX request in play2 - ajax

i'm using play framework 2.0.4
i have a route :
POST /addMail controllers.Application.addMail()
In my controller Application i define the addMail method :
public static Result addMail()
{
JsonNode json = request().body().asJson();
Long id = json.findPath("id").asLong(0);
String email = json.findPath("email").getTextValue();
GameScore gs = GameScore.findById(id);
gs.setEmail(email);
gs.save();
return ok();
}
If i call this method through CURL i have no problem :
curl --header "Content-type: application/json" --request POST --data '{"id": 13, "email": "test#DB.com"}' http://localhost:9000/addMail
But if i call this method through an AJX request i have a 500 response.
$addMailBtn.click(function(event) {
$this = $(this);
var id = $this.attr("id").substring(14);
var email = $("#saisieMailField_" + id).val();
$.ajax({
type: 'POST',
url: "#routes.Application.addMail()",
dataType:"json",
data: {"id":id, "email": '"' + email + '"'},
success: location.reload()
})
} );
If i print in my console my json data, json data is null when i perform my ajax request but is alright through curl.
I have tried to add
#BodyParser.Of(play.mvc.BodyParser.Json.class)
on my method but it doesn't change anything.
Thanks for your time.

This works for me. Note that i stringify the JSON object, and I think this is your problem.
$.ajax({
type: "POST",
url: "http://myservice:9000/api/v1/positions",
data: JSON.stringify({"nwLng":72.22,"nwLat":22.22, "seLng":22.22,"seLat":55.33}),
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (data) { alert(data); },
failure: function (errMsg) { alert(errMsg); }
});

Related

Laravel 5.4 not able to parse FormData javascript object sent using Jquery Ajax

Lately I've been trying to solve an issue with no luck, basically I'm trying to submit a form to the server using AJAX, the form has files, so I'm using the FormData javascript object in JQuery 1.12. The data arrives to the server but in I way I don't know how to format it.
This is my AJAX function:
function saveMenu(id){
var formElement = document.getElementById("menu-form");
var formData = new FormData(formElement);
formData.append('_method', 'PUT');
$( "#form-wrapper" ).toggleClass( "be-loading-active" );
$.ajax({
type: 'PUT',
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
},
url: "{{url('myUrl')}}",
data: formData,
enctype: 'multipart/form-data',
processData: false,
success: function(response) {
toastr.success('Yai! Saved successfully!')
},
error: function(response) {
toastr.error('Oh oh! Something went really wrong!')
},
complete: function() {
$( "#form-wrapper" ).toggleClass( "be-loading-active" )
}
});
}
and when I perform a dd($request->all()); in my controller I get something like this:
array:1 [
"------WebKitFormBoundaryRCIAg1VylATQGx46\r\nContent-Disposition:_form-data;_name" => """
"_token"\r\n
\r\n
jtv4bnn8WQnP3eqmKZV3xWka2YOpnNc1pgrIfk0D\r\n
------WebKitFormBoundaryRCIAg1VylATQGx46\r\n
Content-Disposition: form-data; name="blocks[43][title]"\r\n
\r\n
...
Things I've tried:
Set the HTTP verb to POST. Same result.
Set the AJAX contentType: false, contentType: application/json. Empty response.
Remove enctype: 'multipart/form-data'. Same response.
Any help is appreciated.
This fixed it for me
data: form_data,
contentType: false,
processData: false,
processData: false prevents jQuery from parsing the data and throwing an Illegal Invocation error. JQuery does this when it encounters a file in the form and can not convert it to string (serialize it).
contentType: false prevents ajax sending the content type header. The content type header make Laravel handel the FormData Object as some serialized string.
setting both to false made it work for me.
I hope this helps.
$('#my-form').submit(function(e) {
e.preventDefault();
var api_token = $('meta[name="api-token"]').attr('content');
form_data = new FormData(this);
$.ajax({
type: 'POST',
url: '/api/v1/item/add',
headers: {
Authorization: 'Bearer ' + api_token
},
data: form_data,
contentType: false,
processData: false,
success: function(result,status,xhr) {
console.log(result);
},
error: function(xhr, status, error) {
console.log(xhr.responseText);
}
});
});
also remember to use $request->all(); $request->input() excludes the files
I've been trying to debug that for 2 hours and i found out that method PUT is not working with formData properly.
Try changing
type : "PUT"
into
method : "POST"
Then change your method on your backend from put to post and you'll see the difference.
I used below codes to test it
$("#menu-form").submit(function (){
var fd = new FormData();
fd.append('section', 'general');
fd.append('action', 'previewImg');
fd.append('new_image', $('.new_image')[0].files[0]);
$.ajax({
method : 'POST',
headers: {
'X-CSRF-TOKEN': '{{ csrf_token()}}'
},
url: "{{url('upload-now')}}",
data : fd,
contentType: false,
processData: false,
success: function(response) {
console.log(response);
},
});
return false;
});
And in my controller
public function test(Request $request){
dd($request->all());
}
Ill try to research more about this issue.
Laravel 7,
if use method PUT in ajax, you can follow
1. change method method: 'PUT' to method: 'POST'
2. add formdata.append with _method PUT like this example :
$('#updateBtn').click(function(e){
e.preventDefault();
var frm = $('#tambahForm');
frm.trigger("reset");
$('.edit_errorNama_kategori').hide();
$('.edit_errorGambar').hide();
var url = "/pengurus/category/"+$('#edit_id').val();
var formdata = new FormData($("#editForm")[0]);
formdata.append('_method', 'PUT'); //*** here
$.ajax({
method :'POST', //*** here
url : url,
data : formdata,
dataType : 'json',
processData: false,
contentType: false,
success:function(data){
if (data.errors) {
if (data.errors.nama_kategori) {
$('.edit_errorNama_kategori').show();
$('.edit_errorNama_kategori').text(data.errors.nama_kategori);
}
if (data.errors.gambar){
$('.edit_errorGambar').show();
$('.edit_errorGambar').text(data.errors.gambar);
}
}else {
frm.trigger('reset');
$('#editModal').modal('hide');
swal('Success!','Data Updated Successfully','success');
table.ajax.reload(null,false);
}
},
error: function (jqXHR, textStatus, errorThrown) {
alert('Please Reload to read Ajax');
console.log("ERROR : ", e);
}
});
});
its works for me
Finally I gave up trying to make it work and tried a more vanilla approach, I still don't know the reason why the request is formated like that, but the XMLHttpRequest() function works perfectly and the migration is not a big deal.
The equivalent of the function I posted about would be:
function saveMenu(action){
var formElement = document.getElementById("menu-form");
var formData = new FormData(formElement);
formData.append('_token', $('meta[name="csrf-token"]').attr('content'));
var request = new XMLHttpRequest();
request.open("POST", "{{url('myUrl')}}");
request.send(formData);
request.onload = function(oEvent) {
    if (request.status == 200) {
      toastr.success('Yai! Saved successfully!');
    } else {
      toastr.error('Oh oh! Something went really wrong!');
}
$( "#form-wrapper" ).toggleClass( "be-loading-active" );
  };
}
Bit late, but;
This will solve your problem;
var formData = new FormData(document.getElementById('form'));
console.log(...formData);
var object = {};
formData.forEach(function (value, key) {
object[key] = value;
});
Then you can send this object to the server. This is much more readable and works great.
OR
You can simply send this directly;
JSON.stringify(Object.fromEntries(formData));
This is the newer approach.
And don't give up :-)

Trying to send multiple parameters to ASP.NET webAPI post method results server error 500

Iam trying to send multiple parameters with complex datatype to POST method in WebAPI but it fails with 500 server error. I will be greatful if somebody help me finding what is missing ?
Ajax:
var x={}
var y={}
$.ajax({
cache: false,
type: "POST",
data: JSON.stringify({xDto:x,yDto:y}),
url: "/api/Info/PostInfo",
dataType: 'json',
contentType: "application/json;charset=utf-8",
success: function(data) {
}
error: function(data) {
alert(JSON.stringify(data));
}
})
Action:
public IHttpActionResult PostInfo(InfoDto xDto,InfoDto yDto)
{
//post xDto and yDto to db
}
I would change the API Parameter to an InfoDto array and retrieve it from the body:
public IHttpActionResult PostInfo([FromBody]InfoDto[] xDtos)
{
}
You also have to change your JavaScript to something like this:
data: JSON.stringify([x, y])

Error when calling the URL for saving JSON in database: String is too long

This is the method from the controller api :
[HttpPost]
public void SaveFloor(int floorID, string json)
{
Floor floor = db.FloorSet.Find(floorID);
floor.SavedJson = json;
floorRepository.Update(floor);
floorRepository.Save();
}
Then I made an ajax call to pass the URL.
function SavingFloor(FloorId, Json) {
$.ajax({
url: "/api/Floor/SaveFloor?FloorID=" + FloorId + "&json=" + Json,
type: "POST",
dataType: 'json',
success: function (data) {
alert('success');
}
});
}
I'm trying to save JSON in database (datatype: nvarchar(MAX)), when I call the URL that executes the saving, I get this error Error HTTP 404.15 - Not Found and it says that the filter module applications is configured to deny a request if the string is too long.
So, what should I do? the JSON that I generate is in fact supposed to be too long, and that's the purpose. Please help.
Send the JSON string as the POST body not as part of the URL. Send it as text and json_decode on the server.
function SavingFloor(FloorId, Json) {
$.ajax({
url: "/api/Floor/SaveFloor?FloorID=" + FloorId,
type: "POST",
data: Json,
dataType: 'text/html',
success: function (data) {
alert('success');
}
});
}

ajax POST method is not working

I am trying to send the data via ajax POST method my code is
$.ajax({
url: myUrl + "?token=" + accessToken + "&key=" +dev_key,
dataType: 'jsonp',
type: 'POST',
data: sendXML,
success: function () {
alert("z");
}
});
But the type: 'POST' is not working I am getting the following error on console:
Status Code:405 HTTP method GET is not supported by this URL
Have you tried using $.post ?
Example:
$.post(
myUrl,
{
token: accessToken,
key: dev_key
},
function(result){
alert(z)
}
)
P.S. Isn't ? missing after myUrl?
i think you forgot the ? in the token key like this
mySql + "?token="
otherwise, try this:
jQuery.post(
myUrl + "?token=" + accessToken + "&key=" +dev_key,
sendXML,
function() {
alert('z');
},
'JSONP'
);

jQuery.ajax returns 400 Bad Request

This works fine:
jQuery('#my_get_related_keywords').click(function() {
if (jQuery('#my_keyword').val() == '') return false;
jQuery.getJSON("http://boss.yahooapis.com/ysearch/web/v1/"
+jQuery('#my_keyword').val()+"?"
+"appid=myAppID"
+"&lang=en"
+"&format=json"
+"&count=50"
+"&view=keyterms"
+"&callback=?",
function (data) {//do something}
This returns 400 Bad Request (Just a reformulation of the above jQuery using .ajax to support error handling).
jQuery('#my_get_related_keywords').click(function()
{
if (jQuery('#my_keyword').val() == '') return false;
jQuery('#my_loader').show();
jQuery.ajax(
{
url: "http://boss.yahooapis.com/ysearch/web/v1/"
+jQuery('#my_keyword').val()+"?"
+"appid=myAppID"
+"&lang=en"
+"&format=json"
+"&count=50"
+"&view=keyterms"
+"&callback=?",
success: function(data)
{//do something}
I think you just need to add 2 more options (contentType and dataType):
$('#my_get_related_keywords').click(function() {
$.ajax({
type: "POST",
url: "HERE PUT THE PATH OF YOUR SERVICE OR PAGE",
data: '{"HERE YOU CAN PUT DATA TO PASS AT THE SERVICE"}',
contentType: "application/json; charset=utf-8", // this
dataType: "json", // and this
success: function (msg) {
//do something
},
error: function (errormessage) {
//do something else
}
});
}
Add this to your ajax call:
contentType: "application/json; charset=utf-8",
dataType: "json"
Late answer, but I figured it's worth keeping this updated. Expanding on Andrea Turri answer to reflect updated jQuery API and .success/.error deprecated methods.
As of jQuery 1.8.* the preferred way of doing this is to use .done() and .fail(). Jquery Docs
e.g.
$('#my_get_related_keywords').click(function() {
var ajaxRequest = $.ajax({
type: "POST",
url: "HERE PUT THE PATH OF YOUR SERVICE OR PAGE",
data: '{"HERE YOU CAN PUT DATA TO PASS AT THE SERVICE"}',
contentType: "application/json; charset=utf-8",
dataType: "json"});
//When the request successfully finished, execute passed in function
ajaxRequest.done(function(msg){
//do something
});
//When the request failed, execute the passed in function
ajaxRequest.fail(function(jqXHR, status){
//do something else
});
});
Be sure and use 'get' or 'post' consistantly with your $.ajax call for example.
$.ajax({
type: 'get',
must be met with
app.get('/', function(req, res) {
===============
and for post
$.ajax({
type: 'post',
must be met with
app.post('/', function(req, res) {
I was getting the 400 Bad Request error, even after setting:
contentType: "application/json",
dataType: "json"
The issue was with the type of a property passed in the json object, for the data property in the ajax request object.
To figure out the issue, I added an error handler and then logged the error to the console. Console log will clearly show validation errors for the properties if any.
This was my initial code:
var data = {
"TestId": testId,
"PlayerId": parseInt(playerId),
"Result": result
};
var url = document.location.protocol + "//" + document.location.host + "/api/tests"
$.ajax({
url: url,
method: "POST",
contentType: "application/json",
data: JSON.stringify(data), // issue with a property type in the data object
dataType: "json",
error: function (e) {
console.log(e); // logging the error object to console
},
success: function () {
console.log('Success saving test result');
}
});
Now after making the request, I checked the console tab in the browser development tool.
It looked like this:
responseJSON.errors[0] clearly shows a validation error: The JSON value could not be converted to System.String. Path: $.TestId, which means I have to convert TestId to a string in the data object, before making the request.
Changing the data object creation like below fixed the issue for me:
var data = {
"TestId": String(testId), //converting testId to a string
"PlayerId": parseInt(playerId),
"Result": result
};
I assume other possible errors could also be identified by logging and inspecting the error object.
Your AJAX call is not completed with the following two params.
contentType: "application/json; charset=utf-8",
dataType: "json"
contentType is the type of data you're sending
dataType is what you're expecting back from the server
In addition try to use JSON.stringify() method. It is used to turn a javascript object into json string.

Resources