Curious about what others see as the best way to architect making an API call that depends on the response of another API call in jQuery.
Steps:
Make an API JSONP call to an endpoint, receive response
If we get a 200 success response from the first call, we would trigger another API call (JSON this time).
Output results into browser.
This is how I would construct it with some crude error handling:
$(document).ready(function() {
$.ajax({
url: "http://example.com/json",
type: 'POST',
dataType: 'jsonp',
timeout: 3000,
success: function(data) {
// Variables created from response
var userLocation = data.loc;
var userRegion = data.city;
// Using variables for another call
$.ajax({
url: "http://example2.com/json?Location=" + userLocation + "&City=" + userRegion,
type: 'POST',
dataType: 'json',
timeout: 3000,
success: function(Response) {
$(.target-div).html(Response.payload);
},
error: {
alert("Your second API call blew it.");
}
});
},
error: function () {
alert("Your first API call blew it.");
}
});
});
In terms of architecture, you may consider using Promise pattern to decouple each step into one function, each function cares only about it's own task (do not reference to another step in the flow). This gives more flexibility when you need to reuse those steps. These individual step can be chained together later on to form a complete flow.
https://www.promisejs.org/patterns/
http://api.jquery.com/jquery.ajax/
http://api.jquery.com/category/deferred-object/
function displayPayload(response) {
$(".target-div").html(response.payload);
}
function jsonpCall() {
return $.ajax({
url: "http://example.com/json",
type: 'GET',
dataType: 'jsonp',
timeout: 3000
});
}
function jsonCall(data) {
// Variables created from response
var userLocation = data.loc;
var userRegion = data.city;
// Using variables for another call
return $.ajax({
url: "http://example2.com/json?Location=" + userLocation + "&City=" + userRegion,
type: 'GET',
dataType: 'json',
timeout: 3000
});
}
$(document).ready(function() {
jsonpCall()
.done(function(data) {
jsonCall(data)
.done(function(response) {
displayPayload(response);
}).fail(function() {
alert("Your second API call blew it.");
});
}).fail(function() {
alert("Your first API call blew it.");
});
});
Related
Right now I have a code like this:
$.ajax({
url: apiUrl + valueToCheck,
data: {
format: 'json'
},
error: function () {
},
dataType: 'json',
success: function (data) {
checkAgainstDBHelperWH(data, valueToCheck);
},
type: 'GET'
});
If I am not mistaken, checkAgainstDBHelperWH is known as a callback function. The function executes once the servers sends back response for this particular HTTP /ajax request.
I want to try writing something like the one below, but I don't know what are the effects or is it even logical:
var request = $.ajax({
url: apiUrl + valueToCheck,
data: {
format: 'json'
},
error: function () {
},
dataType: 'json',
success: function (data) {
checkAgainstDBHelperWH(data, valueToCheck);
},
type: 'GET'
})
arrayOfPromises.push(request);
$.when.apply(null, arrayOfPromises).done(function () {
//...some javascript here
});
I want to understand if the .done(function () is fired after the callback function checkAgainstDBHelperWH is completed? Or whatever I am trying to write above does not flow consistently with how ajax works?
Thanks!
I tested it, your code only work if the function(in this case, 'checkAgainstDBHelperWH') doesn't call ajax.
If you want to wait finishing the inner ajax process, use then() and return inner ajax.
var ajaxs =
$.get("xxx").then(function() {
return $.get("yyy").done(function() {
});
});
Here is the jsfiddle.
I'm not sure whether this way is general or not.
I've got a small javascript function that's only purpose is to call a script to get some data from the database so it can be used by other functions on the client side.
I'm using a jQuery call to get the data but for me to pass the object out of the success functions scope I need to turn asynchronous off which raises a deprecation warning.
My function works as intended currently but I'd like to use a method that isn't deprecated. Here is my function:
function getData(ID) {
var Data = {};
$.ajax({
url: 'script',
method: 'POST',
dataType: 'json',
async: false,
data: {action: 'get', id: ID },
success: function(response) {
Data = response;
})
});
return Data;
}
I've changed the variable names for privacy reasons so apologies if they're vague.
Also why is synchronous calls considered harmful to the end users experience?
As AJAX call is asynchronous, you will always get blank object ({}) in response.
There are 2 approach.
You can do async:false
To get response returned in AJAX call try like below code. Which wait for response from server.
function getData(ID) {
return $.ajax({
url: 'script',
method: 'POST',
dataType: 'json',
//async: true, //default async call
data: {action: 'get', id: ID },
success: function(response) {
//Data = response;
})
});
}
$.when(getData(YOUR_ID)).done(function(response){
//access response data here
});
I have trouble async disable ajax. I have the following code:
function GetDataFromUninorte() {
link="http://www.uninorte.edu.co/documents/71051/11558879/ExampleData.csv/0e3c22b1-0ec4-490d-86a2-d4bc4f512030";
var result=
$.ajax({
url: 'http://whateverorigin.org/get?url=' + link +"&callback=?" ,
type: 'GET',
async: false,
dataType: 'json',
success: function(response) {
console.log("Inside: " + response);
}
}).responseText;
console.log("Outside: "+result);
return result;
}
And I get the following result:
"Outside" always runs first
As you can see, "Outside" always runs first and the result is undefined and can not process data.
I have already tried
When ... Then
Async = false
passing data as parameters I / O function
and other things, but nothing
:/
... Beforehand thank you very much
(I am not a native english speaker, I apologize if I do not write well)
[Solved]
Maybe is not the best form, but in the "success:" statement I call a function that receive the ajax response and trigger the rest of the process, in this way I not need store the in a variable and the asynchrony not affect me.
Use can use callbacks, you can read more here
function GetDataFromUninorte(successCallback, errorCallback) {
link="http://www.uninorte.edu.co/documents/...";
$.ajax({
url: 'http://whateverorigin.org/get?url=' + link +"&callback=?" ,
type: 'GET',
async: false,
dataType: 'json',
success: successCallback,
error: errorCallback
});
}
function mySuccessCallback(successResponse) {
console.log('callback:success', successResponse);
}
function myErrorCallback(successResponse) {
console.log('callback:success', successResponse);
}
GetDataFromUninorte(mySuccessCallback, myErrorCallback);
Or you can use promises (bad support in IE browsers)
function GetDataFromUninorte() {
return new Promise(function(resolve, reject) {
link="http://www.uninorte.edu.co/documents/...";
$.ajax({
url: 'http://whateverorigin.org/get?url=' + link +"&callback=?" ,
type: 'GET',
async: false,
dataType: 'json',
success: resolve,
error: reject
});
});
}
GetDataFromUninorte()
.then(function(successResponse){
console.log('promise:success', successResponse);
}, function(errorResponse){
console.log('promise:error', errorResponse);
});
AJAX being asynchronous by nature, you need to pass callback, which will be called when the ajax response is received. You may then access responseText from the xhr object.
You can also you jQuery Deferred and promise to get around your problem like below:
function GetDataFromUninorte() {
var defObject = $.Deferred(); // create a deferred object.
link="http://www.uninorte.edu.co/documents/71051/11558879/ExampleData.csv/0e3c22b1-0ec4-490d-86a2-d4bc4f512030";
$.ajax({
url: 'http://whateverorigin.org/get?url=' + link +"&callback=?" ,
type: 'GET',
async: false,
dataType: 'json',
success: function(response) {
console.log("Inside: " + response);
defObject.resolve(response); //resolve promise and pass the response.
}
});
return defObject.promise(); // object returns promise immediately.
}
and then:
var result = GetDataFromUninorte();
$.when(result).done(function(response){
// access responseText here...
console.log(response.responseText);
});
You should avoid making AJAX synchronous by setting async:false as that will block further interactions on the User Interface.
Use this:
function GetDataFromUninorte() {
link="http://www.uninorte.edu.co/documents/71051/11558879/ExampleData.csv/0e3c22b1-0ec4-490d-86a2-d4bc4f512030";
var result=
$.ajax({
url: 'http://whateverorigin.org/get?url=' + link +"&callback=?" ,
type: 'GET',
**timeout: 2000,**
async: false,
dataType: 'json',
success: function(response) {
console.log("Inside: " + response);
}
}).responseText;
console.log("Outside: "+result);
return result;
}
I have a difficulty to know when all Ajax requests are completed because I need this information to call another function.
Difficulty are to know when my 4/5 function with requests are completed. I use native function of ajax and none is working for me.
I used Chrome, and async requests.
Someone Helps me
I use this(not work):
$(document).ajaxStop(function() {
alert("Completed");
});
and this (not Work):
$(document).ajaxComplete(function() { alert("Completed"); });
Both ways I try use in another function thal calls all requests:
Example:
function Init()
{ Search("123"); Search2("1234"); Search3("12345");
... }
Extract one (of 5 requests,others are very similar ) of my request:
function Search(user) {
$.ajax({
url: 'www.example.com/' + user,
type: 'GET',
async: true,
dataType: 'JSONP',
success: function(response, textStatus, jqXHR) {
try {
if (response != null) {
alert("Have Data");
} else {
alert("are empty");
}
} catch (err) {
alert("error");
}
},
error: function() {
alert("error");
}
}); }
have you tried putting it in a done function? something like...
$.ajax({
url: 'www.example.com/' + user,
type: 'GET',
async: true,
dataType: 'JSONP'
}).done(function (data) {
code to execute when request is finished;
}).fail(function () {
code to do in event of failure
});
bouncing off what Michael Seltenreich said, his solution, if i understand where you guys are going with this...might look something like:
var count = 0;
function checkCount(){
if(count == 5 ){
//do this, or fire some other function
}
}
#request one
$.ajax({
url: 'www.example.com/' + user,
type: 'GET',
async: true,
dataType: 'JSONP',
}).done( function(data){
count += 1
checkCount()
})
#request two
$.ajax({
url: 'www.example.com/' + user,
type: 'GET',
async: true,
dataType: 'JSONP',
}).done( function(data){
count += 1
checkCount()
})
and do it with your five requests. If that works out for you please make sure to mark his question as the answer;)
You can create a custom trigger
$(document).trigger('ajaxDone')
and call it when ever you finished your ajax requests.
Then you can listen for it
$(document).on('ajaxDone', function () {
//Do something
})
If you want to keep track of multiple ajax calls you can set a function that counts how many "done" values were passed to it, and once all are finished, you can fire the event.
Place the call for this function in each of the 'success' and 'error' events of the ajax calls.
Update:
You can create a function like so
var completedRequests= 0
function countAjax() {
completedRequests+=1
if(completedRequests==whatEverNumberOfRequestsYouNeed) {
$(document).trigger('ajaxDone');
}
}
Call this function on every success and error events.
Then, ajaxDone event will be triggered only after a certain number of requests.
If you wanna track specific ajax requests you can add a variable to countAjax that checks which ajax completed.
I have a script that makes two ajax calls - the second being contained within the success handler of the first.
However I need to use the data captured within the first success handler as a further variable to pass in the second ajax call and then use that variable within the php file that is undertaking the server side processing.
This is all very new to me, so I hope this makes some sort of sense. If anyone could assist that would be great.
$.ajax({
type: 'POST',
timeout: 500000,
url: 'processone.php',
data: $('form').serialize(),
success: function (data) {
alert("success data from processone is " + data);
var lead_id = data;
$.ajax({
type: 'POST',
timeout: 500000,
url: 'processtwo.php?lead_id'+lead_id,
data: $('form').serialize(),
success: function (data2) {
alert("success data from processtwo is " + data2)
}
});
}
});
I think you lose a "=" sign in the code:
url: 'processtwo.php?lead_id='+lead_id,
You're going to want to split these into two separate functions and allow for a parameter to be passed to the second. Not really part of your question, but should make it much easier to read. The second process seems to be missing an equals sign in the url parameter which will cause it to not work
function processOne() {
$.ajax({
type: 'POST',
timeout: 500000,
url: 'processone.php',
data: $('form').serialize(),
success: function(data) {
//alert("success data from processone is " + data);
//console logs are better to use when debugging data
console.log('SUCCESS DATA', data);
var lead_id = data;
processTwo(lead_id);
}
});
}
function processTwo(lead_id) {
$.ajax({
type: 'POST',
timeout: 500000,
url: 'processtwo.php?lead_id=' + lead_id,
data: $('form').serialize(),
success: function(data2) {
alert("success data from processtwo is " + data2);
}
});
}
If you're still not getting anything make sure the data is directly returning the lead_id. AJAX calls commonly return JSON data, so it very well might be something like data.lead_id or something like that. Alerts aren't useful for showing this so you could use the console log, console.log('SUCCESS DATA', data) to dig into the return data.
Given the reply to my comment, and making the assumption that the data returned from the first AJAX call is a simple string value (if it's not, you can still use the code here to see how you need to do what you need to do). jQuery's serialize() returns a string (see https://api.jquery.com/serialize/) so you can just append to that.
Also, you are missing your = sign when making your URL, so if you are trying to get the lead_id as a GET var, that's why it's not working.
$.ajax({
type: 'POST',
timeout: 500000,
url: 'processone.php',
data: $('form').serialize(),
success: function (data) {
alert("success data from processone is " + data);
var lead_id = data;
$.ajax({
type: 'POST',
timeout: 500000,
// you are missing the equals sign here, which is why this doesn't work as a GET
url: 'processtwo.php?lead_id'+lead_id,
// here we tack on a lead_id variable to the serialized form and give
// it the value you got back from query 1
data: ($('form').serialize() + "&lead_id=" + lead_id),
success: function (data2) {
alert("success data from processtwo is " + data2)
}
});
}
});