How do I associate an Ajax error result with the original request? - ajax

I am sending data to the server in small bursts using the jQuery ajax function. Each chunk of data is a simple key-value map (the data property passed to the ajax function).
If a request fails, how can my error event handler identify which specific set of data failed to be uploaded?
The function signature of the jQuery error handler is:
error(XMLHttpRequest, textStatus, errorThrown)
Neither textStatus or errorThrown seem useful to identify the failed set of data, and the XHR doesn't seem to offer that capability either.
Simply put, if a request fails, I want to be able to get the id property of the data that I passed to the ajax function. How can I do this?

Check this... From the docs - pay attention to the highlighted section:
The beforeSend, error, dataFilter, success and complete options all take callback functions that are invoked at the appropriate times. The this object for all of them will be the object in the context property passed to $.ajax in the settings; if that was not specified it will be a reference to the Ajax settings themselves.
So, in the error() callback (also success and complete, etc), this will be the object passed to $.ajax() - unless you are using the context parameter to change it.
As a note, the data param passed into $.ajax() will be converted to a serialized string for a GET or POST request
The other option, is to just make sure your error() callback has access to the variable in the same scope:
(function() {
// create a scope for us to store the data:
var data = {id: 1};
$.ajax({
url: '/something-to-genereate-error',
data: data,
error: function() {
console.log(this, data);
}
});
})(); // call the function immediatey
See this fiddle for an example - Note that the data inside of this is "id=1" wereas the data we held a copy of is still {id:1}
Also - Note that the closure here ((function() { .... })()) Is pretty much unnecessary, it is just showing a way to store the data variable before passing it into $.ajax() and the using it in the callback. Most likely this ajax call already lies within a function where you could do this.

Ok, I think I found it (based on my previous answer and the one from gnarf,
$.ajax({
type: "POST",
url: "not-found",
context: {id: 123, name: "hello world"},
error: function(){
console.debug($(this)); //only works in chrome
}
});

Related

using an ajax request in the success function of another ajax function

I'm adding some custom JS to an application built in Wordpress to set appointments so that if an appointment request is made, both the client and worker are sent request emails. The appointment is made by pressing a button, and the request is made by binding the button to the .click() event.
To send the emails, I put the ajax function inside the success function of the first ajax function to approve the appointment, so that if the appointment was approved, the emails are sent. I was trying to set this up, but found that no matter what I did, the second ajax function inside the success function wouldn't fire, and it wouldn't even correctly report what the error was.
To test to see if this was the ajax function itself that was at fault, I took it out of the success function and put it within $(document).ready(function() { }), binding it to a different event to see if it would fire - and it did. So the function itself is not the problem, but rather that it is inside the success function of another ajax request.
What should I do to get this to fire? Other suggestions on Stack Overflow are very confusing at best, so please pardon me for asking again, but there doesn't seem to be a clear satisfactory answer to this.
This is the code that I put within the first ajax request's callback function, which worked perfectly well when I took it outside the callback function and bound it to a different eventy.
$.ajax({
type: "POST",
dataType: "JSON",
url: "[home url]/wp-admin/admin-ajax.php",
data: "action=finchJsonTest",
success: process_lesson_request,
error: function(MLHttpRequest, textStatus, errorThrown){
alert(errorThrown);
alert("Something\'s not right!");
}
});
function process_lesson_request(data) {
alert("Hooray!");
console.log(data);
}
And this is the php function that Wordpress calls to handle this ajax request (determined by the "action" variable in the data string) - there's nothing too important going on, I was just testing to see if it would successfully return a JSON object
function finchJsonTest() {
$json_array[] = 'This is something!';
$finaljson_array = json_encode($json_array);
echo $finaljson_array;
die();
}
add_action( 'wp_ajax_nopriv_finchJsonTest', 'finchJsonTest' );
add_action( 'wp_ajax_finchJsonTest', 'finchJsonTest' );
Again, if I use this ajax call on its own bound to some event, it works perfectly and returns the desired JSON object (just text saying 'this is something'), but if I put this in the success callback function of another ajax request, it fails, and does not even throw what the error is. I have in fact read other Stack Overflow posts related to this, and wasn't able to make heads or tails of what to do. Any thoughts out there?

How to properly clear the content of an Ember.Enumerable?

I was looking at Emberjs recently and found this useful article written by one of its main contributors: Advice on & Instruction in the Use Of Ember.js
It walked me through an example which fetch a list of user data from a server and render them on screen. I'll briefly explain how it worked:
The app contacts the server to fetch a list of user data though ajax
call.
At the end of the ajax call an empty enumerable is returned
immediately, which is later used as a property of a controller.
Once the ajax call is completed, it populates the enum with data which
in turns update the controller's property, and finally triggers an
automatic re-rendering.
This works fine as long as the list is not revisited. As a user revisit the list, say he/she navigates to another state and then comes back, the logic will be triggered again, fetching the data from server and populates the list. However, the list this time is not empty! Thus we have a list of duplicated data. I would like to resolve this by clearing the content of the list when the ajax call is successful. Below is the code for the ajax call:
allAwesomebergs: [],
fetch: function(){
$.ajax({
url: 'https://api.github.com/repos/emberjs/ember.js/contributors',
dataType: 'jsonp',
context: this,
success: function(response) {
response.data.forEach(function(awesomeberg){
this.allAwesomebergs.addObject(App.Awesomeberg.create(awesomeberg))
}, this);
}
});
return this.allAwesomebergs;
},
The above code does not clear the content of the list. I tried adding a line "allAwesomebergs = []" at the beginning of the success function, but what I got was just a blank screen. I thought I may not be doing this correctly, but I looked at the document from Ember and didn't see anything about clearing the content of an Enumerable.
Thus the question is: what is the easiest way to resolve this duplicate loading issue? Clearing the content before hand seems the most obvious but I can't make it work.
You can call clear() before you start adding the new objects. See this documentation.
New code would be:
allAwesomebergs: [],
fetch: function(){
$.ajax({
url: 'https://api.github.com/repos/emberjs/ember.js/contributors',
dataType: 'jsonp',
context: this,
success: function(response) {
this.allAwesomebergs.clear();
response.data.forEach(function(awesomeberg){
this.allAwesomebergs.addObject(App.Awesomeberg.create(awesomeberg))
}, this);
}
});
return this.allAwesomebergs;
},
I think your approach was ok, but it should have been:
this.allAwesomebergs = []
It is all about the this in front of it. So clear is not needed here.

KnockoutJS/AJAX update viewmodel

Currently playing about with KnockoutJS. Just trying to update an observable array from a ajax/json feed (using twitter) in this example.
It seems to lose scope of what "this" is when trying to update my observable array (currentTweets). I've tried adding bind to various places but no such luck.
The error I get is: Uncaught TypeError: Cannot call method 'push' of undefined
I'm sure I am doing something stupid, here it is in action (not much to look at!)
http://jsbin.com/oyuteb
I've read a lot about Knockout mapping but don't feel confident enough to take that on yet!
So, any help or guidance would be fab.
Thanks
The simplest way to solve this is to proxy your viewmodel's "this" into another variable so it is available inside handlers. When jquery ajax calls the success handler, the context is different so this refers to something else.
So you would have
function twitterViewModel() {
var self = this;
this.currentTweets = ko.observableArray([]);
...
this.getTweets = function(){
$.ajax({
dataType: 'jsonp',
url: 'http://search.twitter.com/search.json?callback=?&q='
+ this.searchTerm() + '&rpp=50',
success: function (data) {
$.each(data.results, function(i,tweet){
self.currentTweets.push({'keywords' : 'bugger'});
});
}
});
}
}
You can eliminate the bind calls and use self instead.
Hope this helps.

Using Form Validation submitHandler to send 2 AJAX requests?

I've got a pretty strong understanding of php, html & css but i've only just started to dive into javascript & jQuery.
The problem i'm facing is that I have a form on a page that I want first to validate, then when it passes validation to submit 2 ajax requests; the first to insert data into a table in my database and the second to run a query on another table and return the result.
I've got the latter working just fine using the submitHandler method to send the ajax request and update a div on my page with it's result. When I added a second ajax call after or before this one it seems to break...
My question is should there be a problem with having 2 ajax calls in the submitHandler, like below, and if so what would be the correct way to go about this, or even a better way?
$("#contactform").validate({
rules: ...
submitHandler: function() {
// First to insert the contact details using input#firstname etc.
var firstname = $("#firstname").value();
var lastname = $("#lastname").value();
var contactString = 'firstname='+ firstname + '&lastname=' + lastname;
$.ajax({
type: "POST",
url: "insertcontact.php",
data: quoteString,
success: function(server_response){
$('#yourquote').html(server_response).show();
}
});
// Second use width & height submitted from previous page for processquote.php
var width = <?php echo json_encode($cleanpost['width']); ?>;
var height = <?php echo json_encode($cleanpost['height']); ?>;
var quoteString = 'width='+ width + '&height=' + height;
$.ajax({
type: "POST",
url: "processquote.php",
data: quoteString,
success: function(server_response){
$('#yourquote').html(server_response).show();
}
});
}
});
I'm using the 'jquery.validate.js' validation plugin. Again my goal is such that once someone has entered valid details on my form, using Ajax their contact data is inserted into the database then the database is queried using fields submitted on the previous page to retrieve a numerical result to display on the page, without a refresh.
Any pointers you could give me would be much appreciated!
Rob
EDIT: Learning Javascript & Jquery simultaneously isn't such a good idea it seems, i've confused: this.value = ''; with $(this).val(''); as shown in the first 2 variable declarations, this is what was causing problems! Thanks for your useful help anyway guys, will upboat for your assistance.
In your first .ajax() call, you are trying to pass it a value in the data: parameter that you have not created yet. I believe you are wanting to send it the contactString instead.
Unless your two queries depend on each other being done sequentially then you should be able to execute them both asynchronously (essentially at the same moment). If you want the second AJAX call to happen after the first one, you could always pass all of your data parameters to insertcontact.php and once the insertion is done, execute processquote.php with the values you already passed through.
Lastly, I wonder if you are meaning to do this, but both of your AJAX calls overwrite whatever is in the #yourquote DOM element and show it. You might want to provide a separate element to put the response in for each of your two requests. Perhaps #yourquoteinserted and #yourquoteprocessed?
Edit: BigRob, from your comment it sounds as if you want to make synchronous AJAX queries, check out the async property of your .ajax() call. This is from the .ajax() documentation:
async Boolean
Default: true
By default, all requests are sent asynchronously (i.e. this is set to true by default). If you need synchronous requests, set this option to false. Cross-domain requests and dataType: "jsonp" requests do not support synchronous operation. Note that synchronous requests may temporarily lock the browser, disabling any actions while the request is active.
(emphasis mine)
However, I could be wrong about this but you might actually be able to call one asynchronous AJAX method from within the success function of another. If it starts looking too intermingled for you, you might want to extract the inner call into a function. Rough approximation of what it might look like:
$.ajax({url, data:contactString,
success: function(server_response) {
extractedId = server_response; // you can return data many ways
$.ajax({url2, data:quoteString+"&extra="+extractedId,...
});
}
});
If you perform a synchronous call by setting async:false in the first AJAX call, then you could just store the result into an external (to the AJAX call) variable (or if that doesn't work store it in some DOM element temporarily). Then the javascript will pause execution and won't fire your second AJAX call until the first one has returned.
This is all hypothetical for now, though, and just based off of my understanding of how it should work.

datatable plugin - show and hide more information about a row

datatable plugin - show and hide more information about a row issue :
i want to get that more information by ajax in fnFormatDetails function.but i don't know how do it.i try to put $.ajax in fnFormatDetails function but it seems it have delay to pass the outout to fnOpen function to render new added row ,so the new row is created with empty(undefined) value not the real information.
how can i do that?
thank you.
The "A" in AJAX stands for "asynchronous". When you make an $.ajax call, the function returns before the server has responded, hence "asynchronous". The $.ajax() function has a success callback that receives the server's response, that callback has to do all the work of processing the server's response and updating your page:
$.ajax({
url: '/where/ever',
data: data_for_the_url,
success: function(data, textStatus, jqXHR) {
/*
* This is where you use `data` to update the page.
* $.ajax will call this function when the server
* has successfully responded.
*/
}
});
/*
* When you get here, the server still hasn't responded so you can't
* update your page yet.
*/
So, put all your page updating logic inside the success callback function.

Resources