I'm unsure why this jquery ajax call is failing. Basically, I want to authenticate and if the authentication is a success, do something.
I found this but the answer seems to abbreviated to be much use to me (is assumes you already know how to implement the solution). jQuery ajax return value
Here is my ajax call (I have stripped the fluff for getting the username/password):
function authenticate() {
$.ajax({ //TODO: Securely send this (ssl?)
type: 'POST',
url: 'includes/clientAuthenticate.php',
data: { username: username, password: password},
success:function(data){
if(data==='true') {
return "true";
} else {
return "User failed to log into the system.\nEmail request ignored.\n\nError message: \n" + data;
}
},
error:function(jqXHR, textStatus, errorThrown){
return "User failed to log into the system. Potential problem with server or connection.";
}
});
And I call it in this function:
function attemptEventSubmit(eKey) {
var authReturn = authenticate();
if(authReturn=="true") {
emailEvent(eKey);
} else {
alert(authReturn);
}
}
When it returns, it always alerts that authReturn is "undefined". I suspect it's defining authReturn as undefined because the authenticate function 'finishes' before the ajax call gets back...
But I'm not sure how to fix this problem.
I suspect I could call separate instead of returning values... (say, in this example, calling the emailEvent function directly in the ajax success function) but that would make the authenticate function specific... and it'd no longer be able to be used for authenticating for other purposes.
You can use your code but will need a callback. A better way would be look into promises.
function authenticate(onsuccess, onfail) {
$.ajax({ //TODO: Securely send this (ssl?)
type: 'POST',
url: 'includes/clientAuthenticate.php',
data: { username: username, password: password},
success:function(data){
onsuccess(data); // you should check if this is a function
},
error:function(jqXHR, textStatus, errorThrown){
onfail(errorThrown);
}
});
function attemptEventSubmit(eKey) {
authenticate(
function(ajaxData){
emailEvent('whatever you want to send');
},
function(errThrown){
alert(errThrown);
});
}
How about pass in a callback function as another argument of the function authenticate().
So the code changes will be
function authenticate(callback) {
$.ajax({ //TODO: Securely send this (ssl?)
type: 'POST',
url: 'includes/clientAuthenticate.php',
data: { username: username, password: password},
success:function(data){
if(data==='true') {
//return "true";
callback("true");
} else {
//return "User failed to log into the system.\nEmail request ignored.\n\nError message: \n" + data;
callback("User failed to log into the system.\nEmail request ignored.\n\nError message: \n" + data);
}
},
error:function(jqXHR, textStatus, errorThrown){
//return "User failed to log into the system. Potential problem with server or connection.";
callback("User failed to log into the system. Potential problem with server or connection.");
}
});
Calling the function authenticate will become:
function attemptEventSubmit(eKey) {
authenticate(function(authReturn){
if(authReturn=="true") {
emailEvent(eKey);
} else {
alert(authReturn);
}
});
}
Related
I'm trying to put the infos into my database, for that, this code is in the connexion.jsp which is a page that ask to log with facebook.
the code is supposed to be called into the Controller which is a file in java, and go into the databse.
So my problem is the fact that the code $.ajax doesn't seems to work. It doesn't give a success or error window.alert with or without function(){}.
I might have missed some information about ajax, but i can't find more info about my error.
function fbLogin() {
FB.login(function (response) {
if (response.authResponse) {
// Get and display the user profile data
getFbUserData();
$.ajax({
method: 'post',
url: '/hello/facebookconnection',
first_name: response.first_name,
last_name: response.last_name,
email: response.email,
success:
//success: function(){
window.alert('Sent User data!')//;}
,
error:
window.alert('Error in sending ajax data')
});
else {
document.getElementById('status').innerHTML = 'User cancelled';
}
}, {scope: 'email'});
}
function fbLogin() {
FB.login(function (response) {
if (response.authResponse) {
// Get and display the user profile data
getFbUserData();
$.ajax({
method: 'post',
url: '/hello/facebookconnection',
first_name: response.first_name,
last_name: response.last_name,
email: response.email,
success:
//success: function(){
window.alert('Sent User data!')//;}
,
error:
window.alert('Error in sending ajax data')
});
} else {
document.getElementById('status').innerHTML = 'User cancelled';
}
}, {scope: 'email'});
}
You have a syntax error in front of your else.
I wanted to be able to send the data from a successful jquery ajax call to other methods in my application because its quite large and it made coding sense to have one api method to work from, so I opted to try out promises. This is my first shot. I am getting some good results but clearly I am still a bit confused on context and timing.
When I run the following code, I am unable to wrap my return data from the ajax call as a jquery object without getting an error:
var widgetSystem={
listenForClick: function(){
$('div').on('click','a',function(){
var $selectTarget = $(this),
widgetid = $(this).data('widgetid');
apiRequestData = widgetSystem.makeApiRequestForSingleWidget(widgetid);
apiRequestData.then(function(result) {
widgetSystem.showWidget(result);
}).catch(function(e) {
console.log('no way big error ' +e);
});
});
},
makeApiRequest: function(widgetid){
return new Promise(function(resolve, reject) {
$.ajax({
method: "POST",
url: "localhost",
dataType: 'json',
data: {
data: {
widgetId: widgetid
},
action: 'apiMethod'
},
error: function (jqXHR, textStatus, errorThrown) {
console.log(jqXHR);
console.log(textStatus);
console.log(errorThrown);
reject();
},
success: function (data) {
resolve(data);
}
});
});
},
showWidget: function(data){
$(data).appendTo('body');
//this causes an exception in my apiRequestData.then function in listenForClick
}
}
I am running un minified jquery and getting the following error in my console:
no way big error TypeError: context is undefined
I don't know exactly what your HTML looks like or how the API is set up, but assuming that the API is working correctly and the data sent via POST is correct, I was able to get it working using jsonplaceholder api with the following code (you can find it on JSbin).
var widgetSystem={
listenForClick: function(){
$('div').on('click','a',function(){
console.log('clicked');
var $selectTarget = $(this);
var widgetid = $(this).data('widgetid');
widgetSystem.makeApiRequest(widgetid)
.then(function(result) {
widgetSystem.showWidget(result);
return result;
})
.catch(function(e) {
console.log('no way big error ' +e);
});
});
},
makeApiRequest: function(widgetid){
return new Promise(function(resolve, reject) {
var root = 'http://jsonplaceholder.typicode.com';
$.ajax({
method: "POST",
url: root+'/posts/',
dataType: 'json',
data: {
userId:1,
title:"Havanagila",
body:"Testing the greatness"
},
success: function(xData, status){
resolve(xData);
//reject('whoops');
},
error: function(xhr, status, error){
reject(status);
}
});
});
},
showWidget: function(data){
$('#space').append(document.createTextNode(JSON.stringify(data)));
}
}
widgetSystem.listenForClick()
I don't think there is an issue which how you are calling resolve(data) within the ajax success callback. There may be an issue with the data being sent to your API such that the error callback is called, which in turn calls reject and causes the callback passed to .catch to be called instead of the intended callback passed to .then.
I'm currently dealing with refactoring my code, and trying to automate AJAX requests as follows:
The goal is to have a context-independent function to launch AJAX requests. The data gathered is handled differently based on the context.
This is my function:
function ajaxParameter(routeName, method, array, callback){
//Ajax request on silex route
var URL = routeName;
$.ajax({
type: method,
url: URL,
beforeSend: function(){
DOM.spinner.fadeIn('fast');
},
})
.done(function(response) {
DOM.spinner.fadeOut('fast');
callback(response);
})
.fail(function(error){
var response = [];
response.status = 0;
response.message = "Request failed, error : "+error;
callback(response);
})
}
My problem essentially comes from the fact that my callback function is not defined.
I would like to call the function as such (example)
ajaxParameter(URL_base, 'POST', dataBase, function(response){
if(response.status == 1 ){
console.log('Request succeeded');
}
showMessage(response);
});
I thought of returning response to a variable and deal with it later, but if the request fails or is slow, this won't work (because response will not have been set).
That version would allow me to benefit the .done() and .fail().
EDIT : So there is no mistake, I changed my code a bit. The goal is to be able to deal with a callback function used in both .done() and .fail() context (two separate functions would also work in my case though).
As far as I can see there really is nothing wrong with your script. I've neatened it up a bit here, but it's essentially what you had before:
function ajaxParameter (url, method, data, callback) {
$.ajax({
type: method,
url: url,
data: data,
beforeSend: function(){
DOM.spinner.fadeIn('fast');
}
})
.done( function (response) {
DOM.spinner.fadeOut('fast');
if (callback)
callback(response);
})
.fail( function (error){
var response = [];
response.status = 0;
response.message = "Request failed, error : " + error;
if (callback)
callback(response);
});
}
And now let's go and test it here on JSFiddle.
As you can see (using the JSFiddle AJAX API), it works. So the issue is probably with something else in your script. Are you sure the script you've posted here is the same one you are using in your development environment?
In regards to your error; be absolutely sure that you are passing in the right arguments in the right order to your ajaxParameter function. Here's what I am passing in the fiddle:
the url endpoint (e.g http://example.com/)
the method (e.g 'post')
some data (e.g {foo:'bar'})
the callback (e.g function(response){ };)
Do you mean something like this, passing the success and fail callbacks:
function ajaxParameter(routeName, method, array, success, failure) {
//Ajax request on silex route
var URL = routeName;
$.ajax({
type: method,
url: URL,
beforeSend: function () {
DOM.spinner.fadeIn('fast');
}
}).done(function (response) {
DOM.spinner.fadeOut('fast');
success(response);
}).fail(function (error) {
var response = [];
response.status = 0;
response.message = "Request failed, error : " + error;
failure(response);
})
}
Called like:
ajaxParameter(
URL_base,
'POST',
dataBase,
function(response){
//success function
},
function(response){
// fail function
}
);
Okay, I do use firebug to determine when a function is not defined in Dev. What I would like to do in production is show a modal window saying an error has been received which would then redirect them to another page upon click. Not so easy.
Please understand that this function does work and the component that is called works. I am going to misspell the function call on purpose to demonstrate the error I am not receiving thru the jquery ajax function.
I am using .ajaxSetup to set up the default options for several ajax functions that will be running asynch:
$.ajaxSetup({
type: "POST",
dataType: "json",
url: "DMF.cfc",
data: {
qID: 1,
returnFormat: "json"
},
beforeSend: function() {
$('#loadingmessage').fadeIn(); // show the loading message.
},
complete: function() {
$('#loadingmessage').fadeOut(); // show the loading message.
}
}); //end AjaxSetup
The actual ajax call is:
$.ajax({
data: {
method: 'getCurrentIssues'
},
success: function(response) {
nsNewDebtshowDebtIssues(response);
},//end success function
error: function(jqXHR, exception) {
alert("Error running nsNewDebt.showDebtIssues");
}
}) //end getCurrentIssues Ajax Call
The error I forced is that the method run in the success function should actually be nsNewDebt.showDebtIssues. Firebug correctly displays in console the error nsNewDebtshowDebtIssues is not defined but the actual error message for the ajax call does not run, so if an enduser was running the page it would appear the page was hung.
So, In summary I want to know how to track when such an error occurs, preferrable to place in the error section of the .ajaxSsetup but if neccessary in each .ajax call.
It is not an ajax error, so you cannot handle it from the ajaxError method.
You should do a try/catch in the success method.
success: function(response) {
try {
nsNewDebtshowDebtIssues(response);
} catch (ex) {
//exception occured
//alert("Error running nsNewDebt.showDebtIssues");
alert( ex.message + '\n\tin file : ' + ex.fileName + '\n\t at line : ' + ex.lineNumber);
}
}
Before making the call, you can do:
if(typeof nsNewDebtshowDebtIssues == 'function') {
// .. call it ..
}
Well, the error actually occurs after the AJAX call has succeeded (since it comes from your success handler), so the error handler indeed won't be called.
If you want to use the same handler for actual AJAX request errors and for further errors originating from your success handler, you can define a named function and use it both as your error handler and from a try/catch block in your success handler:
function handleError(jqXHR, status, exception)
{
alert("Error running request.");
// Or print something from 'jqXHR', 'status' and 'exception'...
}
$.ajax({
data: {
method: "getCurrentIssues"
},
success: function(response, status, jqXHR) {
try {
nsNewDebtshowDebtIssues(response);
} catch (x) {
handleError(jqXHR, status, x);
}
},
error: handleError
});
I'm building a RESTful web api with asp.net mvc, which returns pure json data. On my client, I'm using backbone.js to communicate to it.
My question is, how do I capture the message in javascript? For eg. What if a user has no permission to delete or there was no item matching the id? I've been told to throw http errors instead of custom json.
So my code would be:
[HttpDelete]
public ActionResult Index(int id)
{
if (id == 1)
{
throw new HttpException(404, "No user with that ID");
}
else if (id == 2)
{
throw new HttpException(401, "You have no authorization to delete this user");
}
return Json(true);
}
How do I access the message in my javascript callback? The callback would look like:
function (model, response) {
alert("failed");
//response.responseText would contain the html you would see for asp.net
}
I do not see message i threw in the exception anywhere at all in the data that was returned from the server.
You should use the error callback on the client. The success callback is triggered only when the request succeeds:
$.ajax({
url: '/home/index',
type: 'DELETE',
data: { id: 1 },
success: function (result) {
alert('success'); // result will always be true here
},
error: function (jqXHR, textStatus, errorThrown) {
var statusCode = jqXHR.status; // will equal to 404
alert(statusCode);
}
});
Now there is a caveat with 401 status code. When you throw 401 HTTP exception from the server, the forms authentication module intercepts it and automatically renders the LogIn page and replaces the 401 status code with 200. So the error handler will not be executed for this particular status code.
I just answered this in my question What is the point of HttpException in ASP.NET MVC, but you can actually get that string if you use the HttpStatusCodeResult like this:
In your controller:
return new HttpStatusCodeResult(500,"Something bad happened")
And you can access "Something bad happened" using, say, jQuery $.ajax() like this:
$.ajax: {
url: "#Url.Action("RequestsAdminAjax", "Admin")",
type: "POST",
data: function(data) { return JSON.stringify(data); },
contentType: "application/json; charset=utf-8",
error: function (xhr, textStatus,errorThrown) {
debugger;
toggleAlert('<strong>Error: </strong>Unable to load data.', 'alert alert-danger');
}
},
and errorThrown will contain "Something bad happened".
HTH.