$.ajax success function wait - javascript

Due to the (my perceived) nature of the $.ajax GET I'm not sure what I'm looking for is possible in this method, but thought I should ask as it's causing me some trouble. I am in no way an expert on JS, apologies if this is obvious, the title is poor, couldn't think of a different way to say it.
What I'm doing - using $.ajax to get values from the back-end API functions (these work). In the success property I'm using an anonymous function to pass more data across that would not otherwise be brought back. When stepping through the console breakpoints in the Chrome console the success function is often skipped as it's not brought back quick enough.
What I would like - in the example below, I don't want getStuff to complete, before its success DoSomething has returned, as I'm missing loads of data from the API which I need to pass through to DoSomething - is this possible to achieve?
Example
function getStuff(id, hid) {
$.ajax({
type: "GET",
url: "/api/GetMyStuff/" + id,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (vData) {
DoSomething(vData, id, hid); // not always being hit
}
});
}

You could use the async option and set it to false to get a synchronous call:
function getStuff(id, hid) {
$.ajax({
type: "GET",
url: "/api/GetMyStuff/" + id,
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false, // HERE
success: function (vData) {
DoSomething(vData, id, hid); // not always being hit
}
});
}
But that is not a good way to do ajax request, you should rethink your code organization (like giving a callback function to your getStuff method and calling it in the success callback).

What you are trying to do is impossible. Asynchronicity is "leaky", meaning that any asynchronous action requiring a callback (e.g., $.ajax()) necessarily forces asynchronous control flow all the way up the call chain.
Please note that in the near future (thanks to async/await in ES7), this situation gets a little better. The asynchronicity is still leaky, but the new keywords make the refactoring scenario a little easier than hand-jamming callbacks everywhere.

Related

Put ajax response attribute in to a variable for Google Books cover image

I am trying to put a url from an ajax response into a variable in jquery.
I have written the following code:
var thumb = $.ajax({
dataType: 'json',
url: 'https://www.googleapis.com/books/v1/volumes?q=isbn:' + isbn,
success: function(response){
return $(response).volumeInfo.imageLinks.thumbnail;
}}).responseText;
It was my understanding from looking at other answers that I must add .responseText at the end, or the code will continue without waiting for the ajax response.
However, thumb variable remains undefined.
I tried implementing the following solution with relevant changes (As I am passing only one ISBN at a time, there shouldn't be an array. The response should contain only one imageLinks.thumbnail url), but I cannot seem to catch the response correctly.
I looked into other answers, especially this one, but I am still not clear about how to reach the ajax response.
$.ajax is asynchronous, meaning the code will execute completely and the success callback will be fired at a later time.
var thumb is evaluated immediately. Do some reading on "callbacks" and "promises" to get more familiar with this topic.
A solution to your issue is:
function setThumbnail(thumbnail){
// this will evaluate later, when the ajax returns success
console.log('thumbnail gotten!');
var thumb = thumbnail; // do something with in in this function
}
$.ajax({
dataType: 'json',
url: 'https://www.googleapis.com/books/v1/volumes?q=isbn:' + isbn,
success: function(response){
setThumbnail($(response).volumeInfo.imageLinks.thumbnail);
}
});
// This line will evaluate immediately and carry on
console.log('ajax executed');
I threw in some logs for you to help you understand the order of execution here.
I would also note that $(response) looks odd to me, without testing it I think it should probably be just response.volumeInfo....
console.log(response) in the success callback to make sure you understand what data you are getting back.

Asynchronous angularJS - how to wait each request callback?

I'm building an angular application, there are many ajax calls.
I need to wait for each call response to get data from it, that why I make the
synchronous.
$.ajax({
type: "POST",
url: servicePath,
cache: false,
contentType: "application/json; charset=utf-8",
dataType: "json",
async: false,
data: "{}",
success: success,
error: error
});
But this is a problem because if I call "showPleaseWait()"(this is a loading popup) it is not showing, because DOM is not updating unless ajax call is not complete.
It's showing if I'll make my call async, but I can't get my data that time.
Please, can you help me to solve this problem?
If you build a angular app you should take a look at https://docs.angularjs.org/api/ng/service/$http or https://docs.angularjs.org/api/ngResource/service/$resource
If you need to make the ajax calls one after another you can take a look at chaining promises
var a = $http.get('/your-url');
var b = a.then(function(result) {
// use the results here ...
return $http.get('/your-other-url');
});
b.then(function(result) {
// use the results here ...
})
Its not uncommon for Angular beginners to be thoroughly confused, however you are going wrong in two places. I would recommend some studying. Without encouraging spoon-feeding, here are some good places two start.
You need to read about what's the right way to make ajax data calls in angular. Here's a good place to start :(https://github.com/johnpapa/angular-styleguide#data-services)
Use of JavaScript promises in Angular (https://github.com/johnpapa/angular-styleguide#return-a-promise-from-data-calls) .
All this because you did say you want to use angular.However, lookup how you can use promises with $ajax function in jQuery
Maybe try to call your showPleaseWait() function, then the $scope.$apply() from angular right before to send the ajax request? It should force angular to refresh the display.

Ajax Call Sequence in a function

I have a little question. say i have a js function
$(function() {
$(".button").click(function(){
var id=$(this).attr('id');
var dataString = 'id='+ id ;
$.ajax({
type: "POST",
url: "download_number.php",
data: dataString,
cache: false,
success: function(html)
{
$("#div_"+id).html(html);
} });
window.open('File_download.php?file_id='+id, '_blank' );
});
as you can see window.open call is after $.ajax call
Does it guaratee that $.ajax call will get executed every time before the page reloads and if no then
shouldn't we declare window.open in success function?
In my opinion when there is slow response from server the page will reload first and it may happen that $.ajax call will be interrupted by window.open function
but i get a downvote for the same reason here stackoverflow.com/questions/12908138/how-to-get-the-id-or-name-of-related-file/
And Thanks for making my belief stronger
In your example, the window.open function will always (!) be called before the success callback function given to the ajax call. Ajax traffic is always asynchronous, whereas the window.open function resides in the synchronous JS <script> tag.
Since JavaScript is single-threaded, all synchronous statements will always be executed before any asynchronous functionality like ajax setTimeout animate etc.
$.ajax({
type: "POST",
url: "download_number.php",
data: dataString,
cache: false,
success: function(html) { // asynchronous functionality
$("#div_"+id).html(html);
}
});
// within synchronous script statements
window.open('File_download.php', '_blank' );
Yes, Ajax is asynchronous so you will open that window right after you started the XHR process. To download the processed data, open the new window from the success callback. Yet I'm not sure what you mean by "before the page reloads" - there is no code which does that.
Also I don't know how your server behaves, the file_download.php seems to be independent from your ajax call. Shouldn't you pass the download_number you received via ajax in there?

$.ajax Deferred object

These two codes (1)(2) seems to work in the same manner to me.
My questions are:
1) Are these two codes equivalent?
2) If yes why? If not what should I prefer and why?
(1)
$.ajax({
url: backendRouter.generate('feedback_send'),
type: 'POST',
dataType: 'json',
data: data
success: callback,
done: function () {
// some code
}
});
(2)
$.ajax({
url: backendRouter.generate('feedback_send'),
type: 'POST',
dataType: 'json',
data: data
success: callback
}).done(function () {
// some code
});
Yes, the two codes are equivalent, except that (by mistake?) you've left success: callback in the latter.
However IMHO the latter is preferred as deferred objects are far more flexible than supplying a callback directly to $.ajax.
In particular, using deferred objects allows for much better separation of logic and responsibility between initiating the AJAX call and the processing of the results of that call. Also, some of the AJAX helper functions don't support an error callback. If I write:
function doAjax() {
return $.get(...);
}
I can then attach arbitrary numbers of done and fail handlers to the result of that function call, without ever having to pass those handlers into the doAjax function.
I can also combine the returned promise() object with other promises using $.when(), $.pipe(), etc, for very powerful synchronisation between multiple asynchronous events (including other AJAX calls, timers, animations, etc). I can't do that using success:

Success Event does not Fired

$.ajax('http://blog.yahoo.com/#apac3/ajax/getComment?ugcId=68197&commentCount=30&ownerGuid=IQDTYHIWBYN4PPB6DXQWU7JWN4&page=2&type=blog&.crumb=UxHpRaVVUMo&jsoncallback=?', {
type: "GET",
crossDomain:true,
async: false,
dataType: "jsonp",
success: function(comment){
alert("myObject is " + comment.toSource());
}
});
I can see some callback is in chrome's console, however, there is some errors that making success event cannot function normally.
Does anyone know how to obtain the values in the callback?
Your biggest issue is that comment is probably not an instance of a class but is either a string or is a basic JSON object. Unless you have some library which will change the way that Strings or JSON work by modifying the prototypes.

Categories

Resources