Right off the bat I want to apologize that I am not posting code with this. I'm in a car working on a project and I have no internet. I am on the awesome stack exchange app.
Anyway, I am currently working with two separate API calls that I know work separately, but I need to use data from the first call to pass to the second one in order to use the second one dynamically. The reason being, the first AJAX request is a call to Google's geocoding API to get the latitude and longitude of an address. The second requires latitude and longitude as URL parameters.
I looked into using jQuery $.when and .then, but I can't figure out how to pass the data from one AJAX request to the other. I have also tried to build to separate functions and use one inside of the other.
I guess my question is would this be the most efficient way to do this? If it is how do I pass the data.
Side note, responses in jQuery are good for now. I am eventually going to convert this all to Node, but I just want to get the method down first.
if i got you correct, u can call the second ajax request in the success callback of the first one like below example
$.get('ur resource URL',function(data){
$.get('new resource URL',{param1: data.param1, param2: data.prama2}, function(data2){
console.log(data2);
});
});
Here's an example using $.post():
$.post("url_with_address", function(data){
// process geocode API response
$.post("url_with_lat_long", function(response){
});
});
You can use a tried and tested async utility library such as async. This will future proof your code, as it will work in the browser as well as in Node.
In specify, take a look at the waterfall method which allows you to chain together a number of async calls, this will help you manage the code if you need to add more dependent async calls in the future.
The structure of the waterfall function is as follows.
async.waterfall([
function(callback){
$.post('http://google.com/api/...', data, callback);
},
function(results, callback){
$.post('http://google.com/api/...', results, callback);
}
], function (err, result) {
// all done
});
If you want to use jQuery, then the $.when utility won't be that helpful, as it only resolves when every promise has resolved and you want to intercept the data before then.
The simplest way, of course, is to make the second AJAX request within the callback for the first one. However, that is a surefire way to get you on the path to callback hell.
Related
I have an object which acts as a client side API Client which exposes several functions which all return jQuery ajax() objects. Some of those ajax calls have .done() and .fail() calls chained directly onto them because they are actions which need to be taken every time the API responses come back before the rest of the js code is allowed to deal with the response. Pretty standard stuff.
I need to kick off a variable number of API requests, wait for all to fail or succeed, and then continue processing. For the examples I will create, I will simplify this down to just two ajax calls.
So I create an array to hold the returned ajax objects, and then use $.when().apply(null, deferreds).then(function(){//do something after both ajax requests complete}). When the calls complete successfully, everything works great. When calls fail (such as if the ajax call 404s), things are not so great.
The problem is that .then() doesn't seem to detect the fails, even though I thought then() was supposed to be fired regardless of success or failure of the underlying promise(s).
I can switch to .always(), which seems to work better (in that it detects the failures and still triggers the callback) but it seems to fire before some of the .fail() callbacks that are registered directly on the ajax calls, which doesn't make sense to me since I thought the callbacks for an ajax call were called in the order they were registered.
I'm sure I'm just missing something about the behavior of the ajax() when() then() combo.
Fiddle showing successful calls using .then(): https://jsfiddle.net/kwrLyw6q/5/
Fiddle using .then() with failed ajax calls (not working, would love to know why. Seems like this is the "right" way to do it, but I can't figure out where I'm going wrong): https://jsfiddle.net/kwrLyw6q/2/
Fiddle using .always() (working, but notice the out-of-order callback order. At least, out of order compared to the order I want them!): https://jsfiddle.net/kwrLyw6q/7/
It looks like deferred.then() takes three arguments:
success function (first argument).
fail function (second argument).
progress function (third)
updated fiddle
I'm looking for a tried and true way of handling asynchronous calls to API endpoints returning JSON (using polymer's latest rendition of the iron-ajax element). These API calls rely on etag matching, so it is important that the etag sent matches the one on the server. I have that part working, except in certain circumstances, where quick succession API calls may cause an out-of-sequence response (and therefore can get the etag out of sync). There are also multiple API endpoints (i.e. different URLs). So, sometimes if quick succession calls using different endpoints are initiated via an iron-ajax element, it can cause issues for the response handler function, as the response handler currently checks the URL of the ajax element to know how to handle the response appropriately. Therefore, if the 2nd call overwrites the URL of the ajax component before the 1st call response is received, when the 1st call does come back the responseHandler doesn't handle it appropriately. Perhaps there is a much better and reliable way of checking exactly which call has returned?
I know I'm not the first person to encounter this scenario, so I'm wondering if someone out there can show me the enlightened path? I'm thinking there is a simple strategy to handle this problem, perhaps implementing call queuing etc., but I'm not sure if iron-ajax has anything built-in that could help in that regard.
An example with some sample code would be absolutely stupendous!
If you depend on multiple API endpoints, I would have a separate iron-ajax element for each one so that they don't stomp on each other if the URLs change (through data-binding or something):
<iron-ajax id="cats" url="https://api.example.com/cats" handle-as="json"></iron-ajax>
<iron-ajax id="dogs" url="https://api.example.com/dogs" handle-as="json"></iron-ajax>
Generate the requests, and use Promise.all() to wait for both requests to complete:
<script>
Polymer({
is: 'my-element',
...,
fetchPets: function () {
var catsRequest = this.$.cats.generateRequest();
var dogsRequest = this.$.dogs.generateRequest();
Promise.all([catsRequest.completes, dogsRequest.completes])
.then(function (requests) {
var cats = requests[0].response;
var dogs = requests[1].response;
// do whatever you want from here...
alert(cats.concat(dogs));
});
}
})
</script>
Firstly iron-ajax uses iron-request under the skin and that returns a Promise.
I think what you are trying to achieve is that with a string of sequential calls, you can have the same order of responses, despite them all running, possibly in parallel.
This article has an example of doing this with a set of chapters from a story
http://www.html5rocks.com/en/tutorials/es6/promises/
The article gives an online example here:
http://www.html5rocks.com/en/tutorials/es6/promises/async-best-example.html
In essence it is doing a Promise.all(array of requests).then(...) to give you an ordered array of responses.
If you look at the source code for iron-ajax, you will see how it creates the iron-request, and then uses it. You could do the same but based on the example I have pointed to above.
If I have misunderstood, and you are trying to ensure the requests go out sequentially, then you can still do that with Promises, but instead of using Promise.all, you chain them with .then clauses one after the other.
Hello I have some functions written in a JS file that I need help with, I have three methods structured like so:
writeDetailsToDB(); //writes details to db and returns a status to indicates success
writeOtherDetailsToDB(); //writes details to db and returns a status to indicates success
checkOk(); //checks to see both status were successful
The problem I am having is that the checkOk() is being called before the other two methods can finish executing so it always indicates failure I need to be be able to wait for the other two methods to finish before executing checkOK(). Having looked a AJAX success methods I always find an .ajax() method and URLs and I don't see how they fit my problem.
Please can someone help me!
Use the success handler of each to progress and perform the next method in sequence.
You can find documentation and examples of how to use the "success" of the call here: http://api.jquery.com/jquery.ajax/
EDIT: why the anonymous downvote?
Fetch's success and binds's sync can perform the same operations. Which is a good practice?
closure._allusers.fetch({
reset:true,
success: function(data) {
console.log(data);
alert("Fetch successful");
}
});
closure._allusers.bind("sync", function(data) {
console.log(data.models[0].attributes.result);
});
First difference: success is called just before sync is triggered (can matter if you have to use both for some reason).
Second one, and the most important, they are quite different because one is a listener and the other an option you specify. Apart from being 2 ways of doing things, the listener has the advantage of giving you the opportunity to do something while not caring about the origin. Also, you only have to write it once.
The model sync method is called by Backbone save method to formulate an ajax restful json request. The only time you can bind or override the sync method is when you have a different saving strategy, such as websockets, XML transport, or local storage.
First of all, I must say that I'm very new to Google Closure, but I'm learning :)
Okay, so I'm making a web app that's going to be pretty big, and I thought it would be good to manage all the AJAX requests in one XhrManager. No problem there.
But, is it possible to have some kind of default callback that would check for errors first, display them if necessary and then when it passes, launch the "real" callback? I'm talking about a feature like the decoders in amplify.js. Here's their explanation:
Decoders allow you to parse an ajax response before calling the success or error callback. This allows you to return data marked with a status and react accordingly. This also allows you to manipulate the data any way you want before passing the data along to the callback.
I know it sounds complicated (and it is, really), so the fact that I'm not that good at explaining helps a good deal too, but yeah.
The solution I have in my head right now is creating an object that stores all the 'real callbacks', of which the 'error-checking callback' would execute the correct one after it finished checking, but I feel that's a bit hack-ish and I think there has to be a better way for this.
Since you always have to decode/verify your AJAX data (you never trust data returned from a server now do you?), you're always going to have different decoders/verifiers for different types of AJAX payloads. Thus you probably should be passing the decoder/verifier routine as the AJAX callback itself -- for verifications common to all data types, call a common function inside the callback.
An added benefit of this will be the ability to "translate" unmangled JSON objects into "mangled" JSON objects so that you don't have to do use quoted property access in your code.
For example, assume that your AJAX payload consists of the following JSON object:
{ "hello":"world" }
If you want to refer to the hello property in your code and still pass the Compiler's Advanced Mode, you'll need to do obj["hello"]. However, if you pass in your decoder as the callback, and the first line you do:
var decoded = { hello:response["hello"] };
then do your error checking etc. before returning decoded as the AJAX response. In your code, you can simply do obj.hello and everything will be nicely optimized and mangled by Advanced Mode.