I have an Ajax function that takes in 4 parameters. The url, the data, the success callback and error callback functions. I'm trying to make this Ajax function as reusable as possible. Here's how it looks:
function send_data(url, data, successCallback, errorCallback) {
$.ajax({
url: url,
type: 'post',
data: data,
success: successCallback,
error: errorCallback
});
}
Where the success callback looks like this:
function createMessage(message) {
console.log(message);
}
and error callback looks like this:
function createErrorMessage(message) {
console.log(message);
}
However, when I call the Ajax function with parameters that should return a 400 error bad request, the success function is always fired regardless if it is a 200 or 400 response. I don't understand why the success callback function is firing when only the error function should be firing. However, both are firing. Why is this?
The problem is in these lines
success: successCallback,
error: errorCallback
They both are running immediately one after the other so both are returning their values.
Make an anonymous callback function on both success and error and it will work fine.
success: function() {
successCallback();
},
error: function() {
errorCallback();
}
Related
I make a request to a server with JQuery and the $.when method.
$.when(ajaxRequest(param)).done(function(response){
console.log(responseData);
});
my ajax function looks like this:
function ajaxRequest(param){
var requestedData;
return $.ajax({
type: 'POST',
url: myurl,
data: {
setParam:param
},
error: function(data){
console.log(data);
return(data);
}
});
}
Everything works fine if the server returns a 200 OK. But if there was something wrong the server answers with 500. How can I return the response body to the calling method?
The errorbody is printed with console.log on the ajaxRequest method but its not returned to the calling method?
Given js at Question $.when() is not necessary as $.ajax() returns a jQuery promise object. var requestedData; is not set to a value, would be undefined at .done(); use response available at .then() or .done() as returned data; .then() to handle both success and error responses
function ajaxRequest(param){
return $.ajax({
type: 'POST',
url: myurl,
data: {
setParam:param
}
});
}
ajaxRequest(param)
.then(function(response){
console.log(response);
return response
}
// handle errors at second function of `.then()`
, function err(jqxhr, textStatus, errorThrown) {
console.log(textStatus, errorThrown);
return errorThrown;
});
In $.ajaxSetup.success I want a general piece of code to check something and then the $.ajax.complete callback should not be called. Is this possible? Preferably by doing something in the $.ajaxSetup.success callback and not in every $.ajax.complete callback.
event.stopImmediatePropagation might work, but I don't know how to access event from success.
$.ajaxSetup({
success : function(jqXHR, textStatus, errorThrown) {
alert('this will happen');
}
});
$.ajax({
url: '/echo/json/',
type: 'POST',
complete: function () {
alert('this shouldn\'t happen');
}
});
jsFiddle: http://jsfiddle.net/z4L4z3oo/1/
I've been trying out some jQuery AJAX with my loadTable.php file, which echoes a JSON output. However, I can't seem to get $.ajax or $.get to work. The following code doesn't alert anything at all, even when I put alert functions in both success and failure conditions. Obviously this isn't the final functionality, but even with this simple alert function it doesn't work. What am I doing wrong?
$('#tableLoad').click(function () {
$('#sortable tbody').html('');
$.ajax({
type: 'GET',
url: 'loadTable.php',
dataType: 'json',
data: data,
success: function (data) {
alert('Success!');
},
failure: function () {
alert('Something went wrong!');
}
});
})
Use error, failure is not a valid option, see $.ajax.
error: function (jqXHR, textStatus, errorThrown) {
alert('Something went wrong!');
}
if you are using jQuery >=1.5 $.ajax returns a promise, as does any deferred object. This means you can chain your success or error functions onto the end of the ajax call.
They are, however, referred to as done and fail rather than success or error. In the below example "always" does exactly what it says and is called regardless of success or failure.
$.ajax( "example.php" )
.done(function() {
alert( "success" );
})
.fail(function() {
alert( "error" );
})
.always(function() {
alert( "complete" );
});
I have the following problem:
$('#id').on('click', '.class', function(){
// it is doing something and
// executing AJAX request
// with the data from request it is doing something
} // this is onclick handler
Later in the code I need to execute it as well and after executing I need to run another function which depends on the ajax execution of this onclick handler, so I am doing something like this
$('#id .class').click();
anotherFunction();
It is not working. The problem is understandable, because the ajax request has not finished.
I tried to achieve the right execution using the idea of Deferred object.
$.when( $('#id .class').click() ).then( anotherFunction() );
And using the idea of autoexecuted functions with callback:
(function(o, callback){
$('#id .class').click()
})(null, anotherFunction() );
Both ideas failed.
Is there any way to achieve the intended functionality without modifying anotherFunction() and onclick function?
Not sure if I entirely understand your question, but what keeps you from executing your onsuccess / onerror code in the corresponding $.ajax response methods?
$.ajax({
type: 'POST',
url: "your url",
data: "your data",
error: function(jqXHR, textStatus, errorThrown) { ... },
success: function (data, textStatus, jqXHR) { ... }
});
Also, why don't you put the ajax executing part to an own function and call it from the event handler and on every other place, like this?
function ajaxMe(onerror, onsuccess)
{
$.ajax({
type: 'POST',
url: "your url",
data: "your data",
error: function(jqXHR, textStatus, errorThrown) { onerror(...) },
success: function (data, textStatus, jqXHR) { onsuccess(...) }
});
}
The following two ways of implementing an ajaxRequest (1) (2) should be equivalent.
Having said that:
Why does the unit test (3) that verifies the callback was executed, succeeds in (1) and fails in (2)?
How should I rewrite the test (3) to spy on the success callback in (2)?
If I try to stub jQuery.ajax using sinon and the code (2) I get an error. How should I fix it?
Please, see the comments in code (3) for more details.
(1)
ajaxRequest: function (message, callback) {
return $.ajax({
url: backendRouter.generate('feedback_send'),
type: 'POST',
dataType: 'json',
data: {
message: message
},
success: callback
});
}
(2)
ajaxRequest: function (message, callback) {
return $.ajax({
url: backendRouter.generate('feedback_send'),
type: 'POST',
dataType: 'json',
data: {
message: message
}
}).success(callback);
}
(3)
it("should execute the callback function on success", function () {
spyOn($, "ajax").andCallFake(function(options) {
options.success();
}); // If I use the code (2) I get the following error
// TypeError: Object #<Object> has no method 'success'
var callback = jasmine.createSpy();
ajaxRequest('some message', callback);
expect(callback).toHaveBeenCalled();
});
(4)
it("makes a GET request for todo items", function () {
sinon.stub(jQuery, 'ajax');
backendController.ajaxRequest('some message', sinon.spy());
// Cannot call method 'success' of undefined
});
Here's a walkthrough:
If you use the code in number 2, you are invoking the ajax function on jquery:
return $.ajax({
url: backendRouter.generate('feedback_send'),
type: 'POST',
dataType: 'json',
data: {
message: message
}
...
after calling this function with those parameters, jQuery returns a jqHR that happens to have a success function defined. That success function is then invoked:
...
}).success(callback);
All is well so far until your jasmine test spies on the ajax function. The same options you used to invoke $.ajax are passed to this new spy.
// this is the value of the options parameter
{
url: backendRouter.generate('feedback_send'),
type: 'POST',
dataType: 'json',
data: {
message: message
}
}
When this object is passed, your fake function actually attempts to call options.success, which does not exist! Hence the error.
There is a jquery plugin that uses sinonjs with qunit and provides a much easier way to write ajax tests and get expected results.
Take a look at jqueryspy