I'm developing an jQuery application in where I've a requirement to capture HTTP errors as and when it occurs. Below is my snippet.
// Function to validate URL
function validateURL(url)
{
var pattern = new RegExp();
pattern.compile("^[A-Za-z]+://[A-Za-z0-9-_]+\\.[A-Za-z0-9-_%&\?\/.=]+$");
if (!pattern.test(url))
{
return false;
}
return true;
}
// Generic error handler for handling the webservice requests.
function initWebService(wstype, wsurl,jsonData)
{
// If the method parameter is not either "GET" or "POST" display an error message to the developer.
var msgValidateArgument;
var wsCallStatus;
var callbackData;
if ((arguments[0] != 'GET') && (arguments[0] != 'POST'))
{
//alert("Invalid");
//alert("You must provide a valid http method in your webservice call.");
msgValidateArgument = "You must provide a valid http method in your webservice call.";
return msgValidateArgument;
}
// Making sure whether the developer is passing the required number of parameters.
if(arguments.length < 3)
{
//alert("Some required arguments seems to be missing. Please check your webservice invocation.");
msgValidateArgument = "Some required arguments seems to be missing. Please check your webservice invocation.";
return msgValidateArgument;
}
if (!validateURL(arguments[1]))
{
msgValidateArgument = "You must provide a valid URL in your webservice call.";
return msgValidateArgument;
}
if(arguments[2] != ''){
var response=jQuery.parseJSON(arguments[2]);
if(typeof response =='object'){
//It is JSON
alert(response.toSource());
}
else{
msgValidateArgument = "The JSON data being passed is not in valid JSON format.";
return msgValidateArgument;
}
}
// Making the AJAX call with the parameters being passed. The error handler handles some of the possble http error codes as of now.
$.ajax({
type: arguments[0],
url: arguments[1],
data: arguments[2],
dataType: 'json',
async:false,
statusCode:{
404: function(){
alert('Page not found');
},
500: function(){
alert('Page not found');
},
504: function(){
alert('Unknown host');
}
},
success: function(data){
//alert('Data being returned from server: ' +data.toSource());
//alert('Data being returned from server: ' +data.toSource());
//alert(data);
callbackData = data;
}
});
return callbackData;
}
But, when I programatically change the webservice url to hold a wrong value, and upon calling the html page, I'm able to see an error message in the firebug console, but my snippet doesn't seem to be catching the error at all.
For e.g, While calling the GEONames API, I'm encountering an stating "407 Authorization required" in firebug's console.but even if I handle that status code in my error block, it is not firing.. What could be the reason?.
Don't we have any comprehensive solution for handling these HTTP errors effectively?.
I think there are a few problems with your code ... firstly how is handleError called ? because you call a method called handleError but pass nothing ... im assuming your using .ajax()
You should do it like this :
$.ajax({
statusCode: {
404: function() {
alert('page not found');
},
500: function() {
alert('server error');
}
},
success : {
alert('it working');
},
complete : {
alert('im complete');
});
Related
I'm using jQuery and AJAX in the View to send some data to the Controller that writes it to the database. On success I show a div tag with a green background with "OK" text. But what if I do a check first in the Controller if the data already exist in the database, then I would like to alert the user that the data could not be added. Is there a way to pass some kind of message back to the AJAX script?
I guess the success option is just a confirm of contact with the Controller and not a real confirm that everything is OK and the data has been added to the database!?
What action in the Controller would cause the error function in the AJAX code to run?
Finally I just wonder what kind of return I should use since I'm actually not returning anything?
My script in the View:
$.ajax({
url: "/Orders/AddOrder",
type: "GET",
cache: false,
data: { a: order, b: seller },
success: function () {
console.log('AJAX successful');
// Show confirm message
$(".messageOk").show();
$(".messageOk").text("OK").delay(2000).queue(function () {
location.reload();
});
},
error: function () {
????
},
complete: function () {
????
}
});
Controller:
// Add new Resource
public ActionResult AddOrder(int a, int b)
{
var order = new Order
{
OrderNumber = a,
Seller = b
};
db.Orders.Add(order);
db.SaveChanges();
//return new EmptyResult();
return RedirectToAction("Index", "Home"); // ??????
}
You could return the appropriate HTTP status code from your controller action: 409 Conflict.
if (the resource already exists in db) {
return new HttpStatusCodeResult(HttpStatusCode.Conflict);
}
which will trigger the error AJAX function in which you could check whether you are in this situation and act accordingly:
error: function(jqXHR) {
if (jqXHR.status == 409) {
alert('Sorry but this resource already exists');
}
}
As you can see this way it's up to the view to decide what error messages to display based on proper HTTP status codes returned from the server. This way you are not cluttering the server with view logic.
Along with the correct response status code, you can also pass in your response body error messages from the server may be as JSON string or plain string
Right now, I have a form with several fields and on submit, I want to check if the username is taken or not. If taken, do nothing (show validation error), if not taken, successfully proceed onto the next form.
Here's what I have done so far:
View:
var RequestCreateAccount_Submit = function () {
var res = false;
ValidationAttribute.BlankValue(true);
var form = $('form#RequestCreateAccount');
$.validator.unobtrusive.parse(form);
var res = form.valid();
var data = form.serialize();
if (res) {
$.ajax({
url: Url.getFullUrl('Account/RequestCreateAccount_Submit'),
type: 'Post',
data: data,
cache:false,
success: function (data) {
//Next Dialog
},
error: AjaxLog.HandleAjaxCallFail
});
}
return res;
}
Controller:
[AllowAnonymous]
[HttpPost]
public ActionResult RequestCreateAccount_Submit(UserAccount userAccount)
{
//Check if username is unique
if (!WebSecurity.UserExists(userAccount.UserName))
{
UserSession.AddValue(StateName.CreateOrEditAccount, "CurrentUserAccount", userAccount);
JsonResult res = Json(new { Success = true, data = "", Message = "" });
return res;
}
JsonResult jres = Json(new { Success = false, data = "", Message = "Username is already registered"});
return jres;
}
I tested it with a known username and it did hit the success=false (outside of the if statement) line and it did not go inside the if statment. So I know the validation on the server side works.
However, I am wondering why on the client side, it still success = true and the next dialog appeared. It did not fail on validation. What am I doing wrong on the client side?
The reason is that your controller does actually successfully return a result. It is just that the successful result indicates an error. While logically similar at this point, they are very different. Error is going to be reserved for actual exceptions thrown or 404 no route present type of scenarios.
You should check for the response status inside of your success callback function
dotNetFiddle Demo
$.ajax({
url: Url.getFullUrl('Account/RequestCreateAccount_Submit'),
type: 'Post',
data: data,
cache:false,
success: function (data) {
if(data.Success === false){
AjaxLog.HandleAjaxCallFail();
// this may not make as much sense though
// as the request didn't actually fail, just the action did
//TODO: code for name fail
return;//do not process next dialog
}
//Next Dialog
},
error: AjaxLog.HandleAjaxCallFail
});
The success = false of your result object doesn't means that the request failed. It stands only for data.success, nothing more. The resquest is still successful(HTTP 200), which I think is the right response code. If you return an error code like new HttpStatusCodeResult(404, "error message"); it means that your request failed, but it isn't true.
You request works whatever the result of the check is. So you may check this in your success callback, instead of the error callback:
success: function(data) {
if (data.success) {
//Next Dialog
}
else {
// error message
}
}
I am using $.when to make parallel ajax call to webapi controller and it works perfectly fine. The structure is given below,
$.when(GetDataFromMethodA(),GetDataFromMethodB(),GetDataFromMethodC())
.done(function (responseFromMethodA,responseFromMethodB, responseFromMethodC) {
if (responseFromMethodA != null) {
//do some action
}
if (responseFromMethodB != null) {
//do some action
}
if (responseFromMethodC != null) {
//do some action
}
}).fail(function (xhr, textStatus, errorThrown) {
//which method raised the exception?
});
Methods:
function GetDataFromMethodA() {
var Request = {};
Request.Code = name.find(':selected').val();
return $.ajax({
url: 'api/Data/GetCurrentView',
type: 'POST',
dataType: 'json',
data: Request
});
}
similarly, I have method B and C.
QUESTION:
There are situations where any one of the method fails and based on the failing method, I need to display appropriate message to the user. When anyone of the method fails, the exception is caught in the 'fail' section. But, how to find which method raised the exception?
If you use always instead of done, you can inspect whether the request succeeded with isResolved() or isRejected(), for instance:
$.when(GetDataFromMethodA(),GetDataFromMethodB(),GetDataFromMethodC())
.always(function (responseFromMethodA,responseFromMethodB, responseFromMethodC) {
if(responseFromMethodA.isRejected()) {
console.log('A did not work!');
}
if(responseFromMethodB.isRejected()) {
console.log('B did not work!');
}
// ...etc.
});
Ok, what I am trying to do is alerting ajax errors according to its error codes and I have lots of ajax calls on website so I am using global ajax error handler function.
But what I want is if some ajax call already have default errors then show there not global.
$(document).ready(function(){
$(document).ajaxError(e,xhr,opt){
if(xhr.error){
//Don't do anything
} else {
alert('You have an error');
}
}
}
First Function :
$.ajax({
type:"post",
url:"page.php",
data:"name=mohit&lastname=bumb",
error:function(){
alert('error');
}
});
Second Function :
$.ajax({
type:"post",
url:"page.php",
data:"name=mohit&lastname=bumb",
});
So in 2nd case it should show You have an error and in first case just error
Yes you can, but you have to override jQuery default $.ajax methods. Check the following code that I used in one of my projects. Make sure you load the script just after jQuery.
My scenario was -
The web site had a lot of ajax partial views which had to check whether user is logged in or not. So I had to override jquery calls to check for it.
I also had to show a loader when any ajax call was made.
One more thing, some js are loaded by ajax, so I added a check whether the url is a .js file or normal url.
I have taken out the sensitive codes that were confidential for my project. The rest is here. This might help you.
$(document).ready(function () {
var oldjQuery = [];
oldjQuery["ajax"] = $.ajax;
oldjQuery["load"] = $.load;
var newOptions = [];
//override ajax
jQuery.ajax = function (options) {
newOptions["ajax"] = $.extend({}, options);
//override the success callback
newOptions["ajax"].success = function (data, textStatus, jqXhr) {
try {
if (options.url.indexOf('.js') <= -1) {
//this is a normal success call, do nothing
}
}
catch (err) {
//... my other codes, incase any error occurred
}
if (typeof options.success != 'undefined') {
//the ajax call has a success method specified, so call it
options.success(data, textStatus, jqXhr);
}
};
//override the error callback
newOptions["ajax"].error = function (jqXhr, textStatus, errorThrown) {
try {
if (options.url.indexOf('.js') <= -1) {
//this is a normal success call, do nothing
}
}catch (y) {
//... my other codes, incase any error occurred
}
//the ajax call has an error method specified, so call it
if (typeof options.error != 'undefined') {
options.error(jqXhr, textStatus, errorThrown);
}
};
return oldjQuery["ajax"](newOptions["ajax"]);
};
//override load function
jQuery.load = function (url, data, completeCallback, ignore) {
newOptions["load"].completeCallback = function (d, textStatus, jqXhr) {
try {
if (url.indexOf('.js') <= -1) {
//codes
}
} catch (err) {
try {
//codes
}catch (err2) {
}
}
if (typeof completeCallback != 'undefined') {
//call the default completed callback
completeCallback(d, textStatus, jqXhr);
}
};
return oldjQuery["load"](url, data, newOptions["load"].completeCallback);
};
});
I use Prototype.js to validate a form. For one of the fields, I have the prototype script ajax a request to a file. The file is a simple PHP file and will return '1' if the value is OK and '0' if the value is not OK. I have the script as below, which should work perfectly. The prototype validation is supposed to show a validation error message when a field does not pass validation, and not display / remove the message once the field passes validation. But in this case, even when the ajax file returns '1', the validation will display the error message anyway. Anyone able to help would be greatly appreciated!
['validate-number3', numessage3, function(v) {
new Ajax.Request('test.php?nr='+v, {
method:'get',
onSuccess: function(transport) {
var response = transport.responseText;
if(response == '1'){return true;}else{return false};
}
});
}],
the return value from Ajax.Request is the Ajax.Request object and returns as soon as the request is setup - the onsuccess callback is called after the request has been completed - so checking the results of Ajax.Request is not useful for what you want to accomplish.
The reason that this doesn't work as you expect, this is an asynchronous call which means it will start the call and then return control to the script while it is processing and then run the callbacks when it is completed.
Try it this way
new Ajax.Request('test.php?nr='+v, {
method:'get',
onSuccess: handleResponse
});
function handleResponse( transport ){
var response = transport.responseText;
if(response == '1'){
//everything is OK
}else{
//value is not OK
};
}
I was able to solve my question!
Thanks to this teriffic page: http://inchoo.net/ecommerce/magento/magento-frontend/magento-form-field-ajax-validation/ it was no problem. This is what I ended up with:
var ok = false;
new Ajax.Request('test.php?nr='+v, {
method:'get',
asynchronous: false,
onSuccess: function(transport) {
var response = transport.responseText;
if(response == '1'){ok = true;}else{ok = false;};
},
onComplete: function() {
if ($('advice-validate-number-pay_bank_no')) {
$('advice-validate-number-pay_bank_no').remove();
}
}
});
return ok;