Hi my question is how i would send an error from the grails side after a check, for example in a grails controller being called if i had (don't know if its correct):
if(something){ return error #}
else if(something){ return error #}
else{ return error#}
And then what i would need to do in a js function so that it can receive said errors and then act upon it. ie. Error 200 continues as normal, error 400 renders a new page etc, just need to get to the part of reading this error.
Simple stuff:
def delPhoto() {
Photos ph = Photos.get(params.id as Long)
if (ph) {
doSomething()
// return status 200
render status:response.SC_OK
return
}
//OtherWise return 404
render status:response.SC_NOT_FOUND
}
Now in your gsp java script
$.ajax({timeout:1000,cache:true,type: 'GET',url: "${g.createLink(controller: 'photos', action: 'delPhoto')}",
success: function(data) {
$("#uploads").html(data);
},
statusCode: {
417: function() {
$('#field').css({'color':'white'});
$('#field').html("${g.message(code:'default.false.error')}")
}
},
statusCode: {
404: function() {
$('#field').css({'color':'white'});
$('#field').html("${g.message(code:'default.false.error')}")
}
},
error: function (e) {
}
});
});
So your ajax call then defines for each error message or success what things to update on the page
instead of returning status you can directly set your response status in you controller action like this
response.status = 401
and render anything you want.
And access your response status in your ajax success handler like below
$.ajax({
//...
success: function(data, textStatus, xhr) {
console.log(xhr.status);
}
});
Related
I have submit function on form
Here is code of function
export function submit(): void {
$("#sequence").val(Number($("#sequence").val()) + 1);
$("#search_results").addClass("overlay");
$("#filter_form").submit();
}
this function called in onUpdated method
Here is code
// This is what triggers when we anything has been changed.
function onUpdated(): void {
if (!skipSubmit) {
submit();
}
}
I sometimes have 500 code request from back-end and need to show for example alert on it.
I need to catch 500 status from request.
I wonder how I can do this in this code, because I have only $("#filter_form").submit();?
Thank's for help
you can do something like this:
$('#filter_form').submit(function(event) {
//serialize the data in the form in JSON
var formData = $("#filter_form").serializeObject();
$.ajax({
type : 'POST',
url : //your url
data : formData,
dataType : 'json',
encode : true
}).done(function(data) {
//here it comes if there are no error in the server
}).fail(function(data){
//when it fails (so error 500)
//handle your error
)};
event.preventDefault();
}
You are posting your form synchronously. The browser always show the response for synchronous requests. you have 2 option to show user friendly error messages:
1- The server generates a user friendly html page and returns it to the client (you should handle the error at the server and generate the error page)
2- send request asynchronously (Ajax) and catch the error at the client and show a proper message to the user:
$.ajax(“/url-to-post”, {
data: $("#filter_form").serialize(), // serialize form data
success: function(){
//...
},
error: function(jqXHR, textStatus, error){
//...
},
});
I have a validation model attribute for asp.net web api, and I use jquery ajax call to perform the web api call. However, when my ajax call fail, the ajax error does not return any message in success or fail.
public class ValidationActionFilter : ActionFilterAttribute
{
public override void OnActionExecuting(HttpActionContext actionContext)
{
var modelState = actionContext.ModelState;
if (!modelState.IsValid) {
actionContext.Response = actionContext.Request
.CreateErrorResponse(HttpStatusCode.BadRequest, modelState);
}
}
}
$.ajax({
...,
success: function() {
alert('success');
},
error: function() {
alert('fail');
}
});
To get the response into your done and fail methods, simply do this:
$.ajax( "your ajax object" )
.done(function(data) {
alert(data);
})
.fail(function(error) {
alert(error);
});
When you pass a parameter into the callbacks (done, fail), you are capturing the response. So, if you hit an API to get an array of strings, and it was successful, the array would be inside data.
I have an API controller that returns a HttpStatusCodeResult 200 if it worked and 500 if they weren't able to register. The problem is .done and .fail will both be called no matter what status code is returned. However the information is posted or not posted correctly. Here is my post function. Any ideas what could be causing this would be greatly appreciated?
function register() {
$.post("../api/Register",
{
'Email': $("#rEmail").val(),
'Password': $("#rPassword").val()
})
.done((function () {
alert("Thank you for registering!");
})())
.fail((function () {
alert("Email already exists");
})());
}
Edit: The problem is that it was reloading the page when jquery.unobtrusive is supposed to prevent that from happening. The fix or workaround was changing it to a button and not a form.
Instead of passing the anonymous functions you were invoking it as a IIFE by adding () at the end of the function
function register() {
$.post("../api/Register", {
'Email': $("#rEmail").val(),
'Password': $("#rPassword").val()
}).done(function () {
alert("Thank you for registering!");
}).fail(function () {
alert("Email already exists");
});
}
The problem is you're immediately executing the functions that are getting passed to done and fail. That's causing these functions to be executed right then and there.
So just pass the function itself by changing this
.done((function () {
alert("Thank you for registering!");
})())
to this
.done(function () {
alert("Thank you for registering!");
})
You really shouldn't be sending an http status of 500 on an expected registration failure such as "email already exists" condition... this should be handled by a parameter that denotes success / failure as part of a 200 response.
You can handle unexpected internal server errors (status 500) using success or error callbacks like so:
$.ajax({
url : "../api/Register",
type : "post",
data : {"Email" : "you#example.com", "Password" : "pw"},
dataType : "json",
success : function(response){
// handle http 200 responses
if(response.registrationApproved){
alert("Thank you for registering!");
}else{
alert("email exists");
}
},
error : function(){
// handle 500 or 404 responses
alert("server call failed");
},
complete : function(){
// if needed.. this will be called on both success and error http responses
}
});
I am trying to POST some data to my ASP.Net MVC Web API controller and trying to get it back in the response. I have the following script for the post:
$('#recordUser').click(function () {
$.ajax({
type: 'POST',
url: 'api/RecordUser',
data: $("#recordUserForm").serialize(),
dataType: 'json',
success: function (useremail) {
console.log(useremail);
},
error: function (xhr, status, err) {
},
complete: function (xhr, status) {
if (status === 'error' || !xhr.responseText) {
alert("Error");
}
else {
var data = xhr.responseText;
alert(data);
//...
}
}
});
});
The problem with this script is that whenever I try to post the data, the jQuery comes back in "error" instead of "success".
I have made sure that there is no problem with my controller. I can get into my api method in debug mode whenever the request is made and can see that it is getting the data from the POST request and is returning it back. This controller is quite simple:
public class RecordUserController : ApiController
{
public RecordUserEmailDTO Post(RecordUserEmailDTO userEmail)
{
return userEmail;
}
}
I am not sure how I can get jQuery to print out any useful error messages. Currently when I try to debug the jQuery code using Chrome console it shows an empty xhr.responseText, nothing in "err" object and "status" set to "error" which as you see is not quite helpful.
One more thing that I have tried is to run the following code directly from the console:
$.ajax({
type: 'POST',
url: 'api/RecordUser',
data: {"Email":"email#address.com"},
dataType: 'json',
success: function (useremail) {
console.log(useremail);
},
error: function (xhr, status, err) {
console.log(xhr);
console.log(err);
console.log(status);
alert(err.Message);
},
complete: function (xhr, status) {
if (status === 'error' || !xhr.responseText) {
alert("Error");
}
else {
var data = xhr.responseText;
alert(data);
}
}
});
i.e. using the same script without actually clicking on the button and submitting the form. Surprisingly, this comes back with the right response and I can see my data printed out in console. For me this atleast means that my Web API controller is working fine but leaves me with no clue as to why it is not working on clicking the button or submitting the form and goes into "error" instead of "success".
I have failed to find any errors in my approach and would be glad if someone could help me in getting a response back when the form is posted.
As suggested by Alnitak, I was using complete callback along with success and error ones. Removing complete from my code fixed the issue.
Thanks to Alnitak.
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');
}
}
});