I am use $.ajaxSetup to use a global authorization method, and global error handling in my site. I would like to pass a callback function into the global error method so I can call the function whenever I need to in the global error handler. Here is my $.ajaxSetup:
$.ajaxSetup({
global: false,
// type: "POST",
beforeSend: function (xhr) {
//The string needs to be turned into 'this.pasToken'
//if not us, don't include
if(app.cookieAuth)
xhr.setRequestHeader("Authorization", _this.pasToken);
},
statusCode: {
401: function(){
//Redirect to the login window if the user is unauthorized
window.location.href = app.loginUrl;
},
//This is where I need help
403: function(error, callback){
//Show an error message if permission isn't granted
callback(error);
alert(JSON.parse(error.responseText)['Message']);
}
}
});
Note the 403: status code. I am trying to pass in a callback function, but I don't know how to do it from the individual ajax calls. Anyone have an idea?
The easiest solution; define your own property for ajax options.
$.ajaxSetup({
statusCode: {
403: function(error, callback){
this.callback403(error);
}
}
});
$.ajax({
callback403: function () {}
});
Note, if you change the context option of the ajax request, this may not work.
I am not sure if this is what you are looking for:
$.ajax({
statusCode: {
404: function() {
alert("page not found");
}
}
});
Related
I am using Ajax to login a user into the system.
Ajax success will always run the else statement even if the server returns true Boolean.
In case the login credentials were valid the else statement would run and login failed will show up, but if I refresh the page the user will be logged in.
Basically the if(response) never gets ran even though it is true.
$(function(){
$('#loginButtonIdHead').click(function() {
$.ajax({
url: 'localhost/landing/login',
type: 'POST',
data: {
email: $('#defaultForm-email1').val(),
password: $('#defaultForm-pass1').val()
},
success:function(response) {
if(response){
$('#messageId').text("Login Successful");
} else {
$('#messageId').text("Login Failed");
}
}
});
});
});
The $.ajax() method uses anonymous functions for the success and error callbacks. This version is easier to write, and likely easier to maintain:
$(function(){
$('#loginButtonIdHead').click(function(){
$.ajax({
url: 'localhost/landing/login',
type: 'POST',
data:
{
email: $('#defaultForm-email1').val(),
password: $('#defaultForm-pass1').val()
}, success:function(response) {
$('#messageId').text("Login Successful");
},error: function () {
$('#messageId').text("Login Failed");
}
});
});
});
So if the login are incorrect you should be getting 403 forbidden status from the login api call and that would call the error callback.
Moreover, it's not a good approach to give errors on 200 success status. So the backend developer must update it to the appropriate statuses.
Thanks.
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);
}
});
I have a project in MVC4 with C#. In this project, one of my controllers has a method to be called by an Ajax function:
[HttpPost]
public string EditPackage(int id, string newPkgName)
{
try{
//do logic here
return "OK";
}catch(Exception exc){
return "An error occurred, please try later! " + exc.Message;
}
}
This method is called by the following Ajax functions, using jQuery:
$.ajax({
url: $(this).data('url'),
type: 'POST',
contentType: 'application/json; charset=utf-8',
traditional: true,
data: JSON.stringify({ id: id, newPkgName: newPkgName}),
success: function () {
location.reload(true);
successNotification("Package edited successfuly!");
},
error: function (message) {
errorNotification(message);
}
});
The problem with this code, is that even if the server returns the return "An error occurred, please try later! " + exc.Message; message in the catch, the success function is the one always called.
In order words, I never run the error function no matter what I do.
To fix this I checked the official documentation:
http://api.jquery.com/jQuery.ajax/
However, since I am failry new to this I can't understand any of the parameters, nor how to use them effectively.
How can I create a good error message with all the possible information using Ajax, jQuery and my controller?
The error part of the $.ajax call only fires if the returned status code is anything other than 200 OK. In your case you are returning a plaintext response which will therefore be 200. You can change this behaviour like this:
try {
// do logic here
return "OK";
}
catch (Exception exc) {
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Bad Request");
}
error: function (jqXHR, textStatus, errorThrown) {
errorNotification(textStatus);
}
You can change the HttpStatusCode to whatever suits your need.
Alternatively, you can keep the 200 response and return JSON with a flag to indicate whether or not the request was successful:
[HttpPost]
public ActionResult EditPackage(int id, string newPkgName)
{
try {
//do logic here
return Json(new { Success = true, Message = "OK"});
}
catch (Exception exc) {
return Json(new { Success = false, Message = "An error occurred, please try later! " + exc.Message });
}
}
Then you can remove the error handler, and check the state of the flag in your success handler:
success: function(response) {
if (response.Success) {
location.reload(true);
successNotification("Package edited successfuly!");
}
else {
errorNotification(response.Message);
}
},
I do the following, it might not be the best approach but it works for what I try to do.
[HttpPost]
public ActionResult EditPackage(int id, string newPkgName)
{
try{
//do logic here
return Json(new {Success = true, Message = "OK"});
}catch(Exception exc){
return Json(new {Success = false, Message = "An error occurred, please try later! " + exc.Message});
}
}
Then my Ajax looks as follows:
$.ajax({
url: $(this).data('url'),
type: 'POST',
contentType: 'application/json; charset=utf-8',
traditional: true,
data: JSON.stringify({ id: id, newPkgName: newPkgName}),
success: function (data) {
if(data.Success)
{
location.reload(true);
successNotification("Package edited successfuly!");
}
else
{
errorNotification(data.Message);
}
},
error: function (message) {
errorNotification(message);
}
});
I do this so that you have the standard error catching http errors from the server, but it means you can pass a success or failure back in a way that is more useful. It also means that if your update fails for a validation reason or something you can pass that message back nicely.
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
}
});
A team member put this into our project
$(function() {
$("body").bind("ajaxError", function(event, XMLHttpRequest, ajaxOptions, thrownError){
alert(thrownError);
});
}
However I want to supress one of my errors (as it would be noise and verification isn't needed)
function blah() {
...
errFunc = function(event, xhr, opts, errThrown) {
//what could I do here?
//event.stopImmediatePropagation()?
}
$.ajax({
url : '/unimportant_background_refresh',
type : 'GET',
data : { },
dataType : 'json',
success : updateBackgroundStuff,
error : errFunc, // Suppresses error message.
});
}
How can I stop the catch all error from happenning please? Can I just do something in the error function such as { event.StopPropogation(); } or must I work out some mechanism for having the catch all selectively ignore things please?
Global events can be disabled, for a particular Ajax request, by passing in the global option, like so:
$.ajax({
url: "test.html",
global: false,
// ...
});
Taken from: http://docs.jquery.com/Ajax_Events
I would just throw a boolean into your code that's defaulted to false. Set it to true the first time the error is thrown and make sure to check for true at the start of the error function.
Something like:
function blah() {
var errorHappened = false;
...
errFunc = function(event, xhr, opts, errThrown) {
if (errorHappened)
return;
errorHappened = true;
// handle the errror.
}
// the rest of your code
}