I'm using ajax to send a delete request but I am getting a NULL value. I cannot figure out what I am doing wrong.
Here is my ajax call
(function() {
$('#btnDelete').bind('click', function() {
$.ajax({
url: '/Project',
type: 'DELETE',
cache: false,
dateType: 'json',
data: {
delProjId: $('#projectId').text(),
nbRandom: Math.random().toString()
},
success: function(data) {
if (data.message[0].error) {
toastr.error(data.message[0].message);
} else {
toastr.success(data.message[0].message);
console.log('success');
}
},
error: function(request, status, error) {
toastr.error(error);
}
});
});
Here is my post request
protected void doDelete(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
response.setHeader("Content-Type", "application/json");
String delProjId = request.getParameter("delProjId");
System.out.println("Parm:" + delProjId);
}
And the server logs
Parm:null
java.lang.NullPointerException
at com.projectRequest.models.Project.doDelete(Project.java:122)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:210)
It currently is set to span element. I tried putting the value in an input field, even adding a JSON.stringify() around the value as I pass it it. I still get the same results, an empty parameter. I see the value on my client and even when I log it prior to executing the ajax call. I'm not sure what is causing the parameter to clear out.
Only POST request have parameters as an entity in the request body. You must send it as part of the URL.
See RFC 2616: "The DELETE method requests that the origin server delete the resource identified by the Request-URI".
You can pass parameters via URI, for example:
http://localhost/?path=/willbedeleted.txt
Related
I need to send an XML type data to backend using jquery, ajax as a DELETE request. This returns empty array from backend request body. How can I send id properly?
here is my code,
function deleteProduct(id) {
var xmlDocument = $(
`<productsData>
<Prod_ID>${id}</Prod_ID>
</productsData>`);
$.ajax({
type:"DELETE",
url:"http://localhost:8000/delete",
data:JSON.stringify({
data : xmlDocument
}),
contentType: 'application/json',
dataType: 'text'
});
}
I need to send this data,
<productsData>
<Prod_ID>2</Prod_ID>
</productsData>
this 2 comes from the function parameter.
this is my backend in express
app.delete('/delete',(req,res,next)=>{
console.log(req.body);
res.status(200).json({
message: "success"
})
})
this returns empty object.How can I solve this?
If you want to send XML, don't say you're sending application/json:
function deleteProduct(id) {
return $.ajax({
type: "DELETE",
url: "http://localhost:8000/delete",
data: `<productsData><Prod_ID>${id}</Prod_ID></productsData>`,
contentType: 'application/xml'
});
}
By returning the Ajax request, you can do something like this:
deleteProduct(42).done(function () {
// delete completed, remove e.g. table row...
}).fail(function (jqXhr, status, error) {
// delete failed, keep table row & show alert
alert("Could not delete product: " + error);
});
This question already has answers here:
How should I use servlets and Ajax?
(7 answers)
Closed 6 years ago.
i have a username textbox that when a user input a name it takes that name and send to server and the server check if the username has not been taken by anybody else, if so i need to send back somedata and tell the client that the username has been taken else if it is not i need to turn the textbox border color to green, now i can do sending username value to server but i don't know how to send back and how to receive the sent data using jquery ajax.
here is my code:
client:
$(document).ready(function() {
$('#Registeration_Username_box').on('input', function() {
postUsernameToServer();
});
function postUsernameToServer() {
var formData = {
'username': $('input[name=UserName]').val(),
};
// process the form
$.ajax({
type: 'POST', // define the type of HTTP verb we want to use (POST for our form)
url: '../dusernameavailable', // the url where we want to POST
data: formData, // our data object
dataType: 'json', // what type of data do we expect back from the server
encode: true
}).done(function(data) {
console.log(data);
});
}
});
servlet:
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
String str = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
System.out.println(str);
}
Add success and error to your ajax
function postUsernameToServer() {
var formData = {
'username': $('input[name=UserName]').val(),
};
// process the form
$.ajax({
type: 'POST', // define the type of HTTP verb we want to use (POST for our form)
url: '../dusernameavailable', // the url where we want to POST
data: formData, // our data object
dataType: 'json', // what type of data do we expect back from the server
encode: true,
success: function(data) {
//TODO make the box green or whatever your requirement is
},
error: function() {
//TODO username already taken
}
});
}
});
In servlet send appropriate response.
You will need to send a response code other than 200 for ajax to consider it as an error from the server.
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String str = request.getReader().lines().collect(Collectors.joining(System.lineSeparator()));
System.out.println(str);
//TODO - check if user name exists or not
if(user name already exists){
response.setProperty(response.HTTP_STATUS_CODE, "500");
PrintWriter out = response.getWriter();
out.println("error");
out.close();
}
else{
PrintWriter out = response.getWriter();
out.println("success");
out.close();
}
}
}
Add a success handler to your ajax call.
You can try something like below; where 'green' and 'red' are css classes you defined in your CSS file .
$.ajax({
type: 'POST', // define the type of HTTP verb we want to use (POST for our form)
url: '../dusernameavailable', // the url where we want to POST
data: formData, // our data object
dataType: 'json', // what type of data do we expect back from the server
encode: true,
success: function(response) {
if(response.isUserNameAvailable == true)
$('input[name=UserName]').addClass('green');
else
$('input[name=UserName]').addClass('red');
}
}).done(function(data) {
console.log(data);
});
Longer title would be:
"Attempts to use an ajax call to the controller to insert search results into a table result in errors while remaining on the same page results in "405" or "Direct self-reference leading to cycle... " errors"
I am trying to find a way to fill a table with search result while staying on same page using an ajax call to the controller.
ajaxCall->Controller->Service(completes search)->Controller(result from search)->back to ajax with response
I have an ajax call that is triggered on form submit after prevent default:
function ajaxGetSearchResults(link, form) {
var myList=[];
var jqxhr = $.ajax({
"url" : link,
"data" : form.serialize(),
"dataType" : 'json',
"type" : "POST",
"headers": {
'Content-Type': 'application/json'
},
"success" : function (response){
console.log("Ajax success");
fillTable(response);
console.log("Search results added to table: "+response);
},
"complete": function(response){
console.log("Ajax call to controller completed");
},
"error": function(){
console.log("Ajax call to controller triggered error");
}
});
}
In the controller I recieve the ajax request as such:
#RequestMapping(value = "/ajaxScriptSearch", method = RequestMethod.POST)
public #ResponseBody List<ResultViewDto> processAJAXRequestSearch(#RequestParam String a1,
#RequestParam String a2, #RequestParam String a3, #RequestParam String a4) {
SearchDto searchDto = new SearchDto();
searchDto.setAttribute1(a1);
searchDto.setAttribute2(a2);
searchDto.setAttribute3(a3);
searchDto.setAttribute4(a4);
try {
/*
calling Service, performing search using searchDto as a parameter, mapping result to resultViewDtos
*/
} catch(Exception e){
/* do something */
}
return resultViewDtos;
}
The call to the service is successfull.
An example of resultViewDtos would be: [viewDto1, viewDto2, viewDto3] where every view dto contains a number of string values which need to be inserted into a table.
I seem to be getting a "HTTP Status 405 - Request method 'GET' not supported" error, but my ajax call is "type: POST".
When I tried doing it with GET insted, I get an "Direct self-reference leading to cycle (through reference chain...)" error.
I am using jackson-core 2.6.2, jackson-databind 2.6.2, Spring 4, Hibernate 4.
I would appericiate any help I can get...
In the end I managed to create a workaround for this.
I have changed my ajax call as such:
function ajaxGetSearchResults(link, form) {
var jqxhr = $.ajax({
"url" : link,
"data" : form,
"dataType" : 'json',
"headers": {
'Accept' : 'application/json',
'Content-Type': 'application/json'
},
"type" : "GET",
"success" : function (response) {
console.log("Ajax success");
fillTable(response);
},
"complete": function(response) {
console.log("Ajax call to controller completed");
},
"error": function() {
console.log("Ajax call to controller triggered error");
}
});
}
And my controller as follows:
#RequestMapping(value = "/ajaxScriptSearch", method = RequestMethod.GET)
public #ResponseBody List<String> processAJAXRequestSearch(#RequestParam String a1,
#RequestParam String a2, #RequestParam String a3, #RequestParam String a4) {
SearchDto searchDto = new SearchDto();
searchDto.setAttribute1(a1);
searchDto.setAttribute2(a2);
searchDto.setAttribute3(a3);
searchDto.setAttribute4(a4);
List<String> result = new ArrayList<String>();
List<ResultViewDto> resultViewDtos = new ArrayList<ResultViewDto>();
try {
/*
calling Service, performing search using searchDto as a parameter, mapping result to resultViewDtos
*/
for(int i=0; i<resultViewDtos.size(); i++){
result.add(resultViewDtos.get(i).toResponseString()); //a new method
}
} catch(Exception e){
/* do something */
}
return result;
}
toResponseString() is a new method I have created in my resultViewDto that returns a string in which the attributes I need are separated by ":".
After filling the result and sending it back to ajax as a response, I then split the recieved response first on (',') to get the individual "rows" equivalent to a single resultViewDto, and then by (':') to get the values for each cell.
There might be a better way of solving it, but this woked like a charm.
I hope this will be usefull for someone else too.
I'm using ASP.Net MVC, but this applies to any framework.
I'm making an Ajax call to my server, which most of the time returns plain old HTML, however if there is an error, I'd like it to return a JSON object with a status message (and a few other things). There doesn't appear to be a way for the dataType option in the jQuery call to handle this well. By default it seems to parse everything as html, leading to a <div> being populated with "{ status: 'error', message: 'something bad happened'}".
[Edit] Ignoring the dataType object and letting jQuery figure out doesn't work either. It views the type of the result as a string and treats it as HTML.
One solution I came up with is to attempt to parse the result object as JSON. If that works we know it's a JSON object. If it throws an exception, it's HTML:
$.ajax({
data: {},
success: function(data, textStatus) {
try {
var errorObj = JSON.parse(data);
handleError(errorObj);
} catch(ex) {
$('#results').html(data);
}
},
dataType: 'html', // sometimes it is 'json' :-/
url: '/home/AjaxTest',
type: 'POST'
});
However, using an Exception in that way strikes me as pretty bad design (and unintuitive to say the least). Is there a better way? I thought of wrapping the entire response in a JSON object, but in this circumstance, I don't think that's an option.
Here's the solution that I got from Steve Willcock:
// ASP.NET MVC Action:
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult AjaxTest(int magic) {
try {
var someVal = GetValue();
return PartialView("DataPage", someVal);
} catch (Exception ex) {
this.HttpContext.Response.StatusCode = 500;
return Json(new { status = "Error", message = ex.Message });
}
}
// jQuery call:
$.ajax({
data: {},
success: function(data, textStatus) {
$('#results').html(data);
},
error: function() {
var errorObj = JSON.parse(XMLHttpRequest.responseText);
handleError(errorObj);
},
dataType: 'html',
url: '/home/AjaxTest',
type: 'POST'
});
For your JSON errors you could return a 500 status code from the server rather than a 200. Then the jquery client code can use the error: handler on the $.ajax function for error handling. On a 500 response you can parse the JSON error object from the responseText, on a 200 response you can just bung your HTML in a div as normal.
While Steve's idea is a good one, I'm adding this in for completeness.
It appears that if you specify a dataType of json but return HTML, jQuery handles it fine.
I tested this theory with the following code:
if($_GET['type'] == 'json') {
header('Content-type: application/json');
print '{"test":"hi"}';
exit;
} else {
header('Content-type: text/html');
print '<html><body><b>Test</b></body></html>';
exit;
}
The $_GET['type'] is just so I can control what to return while testing. In your situation you'd return one or the other depending on whether things went right or wrong. Past that, with this jQuery code:
$.ajax({
url: 'php.php?type=html', // return HTML in this test
dataType: 'json',
success: function(d) {
console.log(typeof d); // 'xml'
}
});
Even though we specified JSON as the dataType, jQuery (1.3.2) figures out that its not that.
$.ajax({
url: 'php.php?type=json',
dataType: 'json',
success: function(d) {
console.log(typeof d); // 'object'
}
});
So you could take advantage of this (as far as I know) undocumented behavior to do what you want.
But why not return only JSON regardless of the status (success or error) on the POST and the use a GET to display the results? It seems like a better approach if you ask me.
Or you could always return a JSON response, and have one parameter as the HTML content.
Something like:
{
"success" : true,
"errormessage" : "",
"html" : "<div>blah</div>",
}
I think you'd only have to escape double quotes in the html value, and the json parser would undo that for you.
I ran into this exact same issue with MVC/Ajax/JQuery and wanting to use multiple dataTypes (JSON and HTML). I have a AJAX request to uses an HTML dataType to return the data, but I attempt convert the data that comes back from the ajax request to a JSON object. I have a function like this that I call from my success callback:
_tryParseJson: function (data) {
var jsonObject;
try {
jsonObject = jQuery.parseJSON(data);
}
catch (err) {
}
return jsonObject;
}
I then assume that if the jsonObject and errorMessage property exist, that an error occured, otherwise an error did not occur.
I accomplished this by using the ajax success and error callbacks only. This way I can have mixed strings and json objects responses from the server.
Below I'm prepared to accept json, but if I get a status of "parsererror" (meaning jquery couldn't parse the incoming code as json since that's what I was expecting), but it got a request status of "OK" (200), then I handle the response as a string. Any thing other than a "parsererror" and "OK", I handle as an error.
$.ajax({
dataType: 'json',
url: '/ajax/test',
success: function (resp) {
// your response json object, see if status was set to error
if (resp.status == 'error') {
// log the detail error for the dev, and show the user a fail
console.log(resp);
$('#results').html('error occurred');
}
// you could handle other cases here
// or use a switch statement on the status value
},
error: function(request, status, error) {
// if json parse error and a 200 response, we expect this is our string
if(status == "parsererror" && request.statusText == "OK") {
$('#results').html(request.responseText);
} else {
// again an error, but now more detailed and not a parser error
// and we'll log for dev and show the user a fail
console.log(status + ": " + error.message);
$('#results').html('error occurred');
}
}
});
I am using jQuery to make an AJAX request to a remote endpoint. That endpoint will return a JSON object if there is a failure and that object will describe the failure. If the request is successful it will return HTML or XML.
I see how to define the expected request type in jQuery as part of the $.ajax() call. Is there a way to detect the request type in the success handler?
$.ajax(
{
type: "DELETE",
url: "/SomeEndpoint",
//dataType: "html",
data:
{
"Param2": param0val,
"Param1": param1val
},
success: function(data) {
//data could be JSON or XML/HTML
},
error: function(res, textStatus, errorThrown) {
alert('failed... :(');
}
}
);
Have you application generate correct Content-Type headers (application/json, text/xml, etc) and handle those in your success callback. Maybe something like this will work?
xhr = $.ajax(
{
//SNIP
success: function(data) {
var ct = xhr.getResponseHeader('Content-Type');
if (ct == 'application/json') {
//deserialize as JSON and continue
} else if (ct == 'text/xml') {
//deserialize as XML and continue
}
},
//SNIP
);
Untested, but it's worth a shot.
how about using the complete option?
$.ajax({
...
complete : function(xhr, status) {
// status is either "success" or "error"
// complete is fired after success or error functions
// xhr is the xhr object itself
var header = xhr.getResponseHeader('Content-Type');
},
...
});
By the time it calls your success handler, the data has already been deserialized for you. You need to always return the same data type for any successful result. If there truly is an error, you should probably throw an exception and let it get handled by the error callback instead. This should be able to parse the resulting error and package it for your callback, that is, it will detect that the response did not have 200 OK status and parse the result to obtain the error information.