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

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?

Related

Is it possible to fire multiple ajax requests asynchronously in Magento 2 backend?

What the title says.
Im trying to run an import script with AJAX "call 1" and I want to keep track of the import (for feedback purposes) with AJAX "call 2".
To give the end user live feedback these calls need to run simultaneously and "call 2" needs to call itself (recursive) to poll for changes.
I have the Controllers and the calls and everything works just fine, just not at the SAME time.
Is it a soft lock on the database or is it something else?
Btw I am aware of the "async: true" setting for the ajax call.
[edit]
It looks like Magento is preventing me from executing two controllers at the same time. Can anyone confirm this?
I think you cannot do two AJAX requests concurrently. This means you always needs to have a logical order, a.k. first 'call 1', then 'call 2'. If you want to make sure call 2 always fires after the call 1 just put it in the success method.
Like so:
$.ajax({
url: "test-to-call-1",
context: call-1-context
}).done(function() {
$.ajax({
url: "test-to-call-2",
context: call-2-context
}).done(function() {
Now both ajax requests are done.
And you could add the context of the first one to the second call.
});
});
If you want to enable polling, just place a setTimeOut loop in which you do the second AJAX call :)
Like this:
function start_polling(counter){
if(counter < 10){ // poll maximum of 10 times.
setTimeout(function(){
counter++;
$.ajax({
url: "test-to-call-2",
context: call-2-context
}).done(function() {
start_polling(counter);
Now both ajax requests are done.
And you could add the context of the first one to the second call.
}).error(function(){
start_polling(counter);
});
}, 1000);
}
}
$.ajax({
url: "test-to-call-1",
context: call-1-context
}).done(function() {
start_polling(0)
});
Well I figured it out.
All I had to do was set:
session_write_close();
In front of the method that started the import and I could start polling with a second AJAX call!
This is probably frowned upon, but it works

why browser request for image after ajax?

I'm using backbone and nodejs for a single page webapp.
I got a view, which has a model(a blog post) in it. when user click on 'like' button, the view will start ajax send the user'id to server to let the like number +1.
it looks like this:
this.model.save({
likedBy: userModel.get('_id')
}, {
url: '/posts/' + this.model.get('_id') + '/like',
success: function() {
// do something
},
patch: true
});
my problem is, when this code got run. browser start http request to retrieve all the images on the screen, and re-render them. so the screen got a "shake" after user clicked the like button.
this is not happening everywhere, but what caused this? how to stop the "shake"?
thanks for any advance.
When you call this.model.save() the model will update his data in the server and will call your view's render function. The render method will create a new DOM element and replace the old DOM element, that's what causing the flickering (it requests the images again).
I assume you have an API call for Like action (if not it's better to have one) so you can make a sperate AJAX call for like action on your model by adding a function like so:
addLike : function(data) {
Backbone.ajax({
url: '/api/like/'+ this.get('id'),
method: 'POST',
data: data,
success: options.success,
error: options.error
});
}

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.

JQuery post not working in document but is working in console?

I have a page which needs to use $.post() but for some reason the exact code works when I run it from the firebug console but not from my script? My script is:
$(document).ready(function () {
$('#dl_btn').click(function () {
$.post(
"news_csv.php",
$("#dl_form").serialize(), function (data) {
alert('error');
if (data == 'success') {
alert('Thanks for signing up to our newsletter');
window.open("<?php echo $_GET['link']; ?>");
parent.Shadowbox.close();
} else {
alert(data);
}
});
});
});
It isn't the link as that does get printed properly but it gives me an error on line 140 of jquery min, I have tried using different versions of jquery and to no avail. I really dont understand why this isn't working.
When I changed from $.post to $.ajax and used the error callback I did receive an error of 'error' and the error is undefined?
Don't suppose anyone has any ideas? Would be much appreciated.
Thanks,
Tom
Is your click button placed inside a form element?
Cause doing so, clicking on it will not only trigger the onClick event you have binded to, but form submit as well, so you will end up in a case where your browser is executing both requests in parallel - with unpredicted outcome, of course.
I tried the same code with an element that does not trigger form submit and it worked as expected.
One point though: if you plan to use simple string as a return value and to do something with it (display it or so) then is ok to do what you do right now. However, if you have more complex response from the ajax request, you should specify the response type (xml, json..) as the last parameter of the post method.
Hope this helps.

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

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
}
});

Resources