Is there a possible way to send the variable, 'schedule_id[i]', with the result of the call. Also is it possible to add this variable in the data object?
My code:
for (var i = 0; i < schedule_id.length; i++) {
//Ajax call
$.ajax({
url: "http://api.viewer.zmags.com/schedules/" + schedule_id[i] + "?key=" + api_key
})
//
.done(function(data){
}
So you need asynchronies ajax call in synchronies manner right?
So you need to create one separate function which is call ajax request and return the result and use in subsequent request.
Like:-
for (var i = 0; i < schedule_id.length; i++) {
var result;
if (i == 0)
result = callfunction(0,schedule_id[i]);
else
result = callfunction(result,schedule_id[i]);
}
function callfunction(passresult,schedule_id) {
$.ajax({
url: "http://api.viewer.zmags.com/schedules/" + schedule_id + "?key=" + api_key
})
.done(function (data) {
return data;
});
}
construct the ajax call like this:
$.ajax({
url: 'http://api.viewer.zmags.com/schedules/',
type: 'POST' // or GET,
data: {
schedule_ids: schedule_id, //array
key: api_key
},
success: function (data) {
//success callback
}
});
Related
I am trying to call an http service within a for loop through a function (callAPI).
Here is my code. The problem I am having with this code is that I don't get the correct id called in the right order when the http service catches up. On the callAPI function it goes through all the calls of console.log(id) before even running one http service async request then it runs the http service calls but with the wrong order of id's..For instance I get back an array of [6,6,3] and it runs it in the order of [3,6,6]. Any help is appreciated.
for (var i = 0; i < idArray.length; i++) {
callAPI(idArray[i]);
}
function getItems() {
return self.choices;
}
function callAPI(id) {
console.log(id);
$http({
method: 'GET',
url: '/api/organizations/' + orgID + '/' + id + '/meal'
}).success(function (data) {
console.log(id);
console.log(data);
// idLocal = id;
angular.forEach(data, function(value,key) {
angular.forEach(value, function(value,key) {
angular.forEach(value, function(value,key) {
if (key == 'description') {
items.push(value);
}
if (key == 'drop_name') {
self.dropName = value;
}
});
});
});
self.choices.push({
id: id,
choice: items,
dropname: self.dropName
});
items = [];
getItems();
}).error(function (data) {
console.log('failed');
});
}
I prefer to do something like this but there are multiple other solutions:
//set index
var index = 0;
function callAPI(id) {
//increment index
index++
$http({
method: 'GET',
url: '/api/organizations/' + orgID + '/' + id + '/meal'
}).success(function (data) {
//call function again with next index if exists
if (index <= idArray.length) {
callAPI(idArray[index])
}
}).error(function (data) {
console.log('failed');
});
}
//call function with 0 index
callApi(idArray[index])
This will run one async request, when that is returned then run the next. You can of course handle the return data any way you want. Also, as mentioned using the promise library included with angular "q" is another good option.
On my code I hava a function with 3 nested AJAX calls, in order for it to work I had to set Async=false.
As I have read that Async=false is deprecated I replaced the Async=false with promises.
This is my function before I edited it:
self.getOrders = function (name) {
var orders= [];
var order= function (item, type1, type2) {
var self = this;
self.order= item;
self.type1= type1;
self.type2= type2;
}
$.ajax({
url: "/API/orders/" + name,
type: "GET",
async: false,
success: function (orderResults) {
var mappedOrders = $.map(orderResults, function (orderItem) {
$.ajax({
url: "/API/orders/property/" + orderItem.id + "/type1",
type: "GET",
async: false,
success: function (property1Results) {
$.ajax({
url: "/API/orders/property/" + orderItem.id + "/type2",
type: "GET",
async: false,
success: function (property2Results) {
orders.push(new order(orderItem, property1Results, property2Results));
}
});
}
});
})
}
});
return orders;
This function worked perfectly, I got the data end everything worked fine.
Then I changed the function to use promises instead of Async=false,
this is the edited function, with promises:
//The begin of the function- same as first one
var orders= [];
var firstPromise = $.ajax({
url: "/API/orders/" + name,
type: "GET"
});
$.when(firstPromise).done(function (orderResults) {
var mappedOrders = $.map(orderResults, function (orderItem) {
var secondPromise = $.ajax({
url: "/API/orders/property/" + orderItem.id + "/type1",
type: "GET"
});
$.when(secondPromise).done(function (property1Results) {
var thirdPromise = $.ajax({
url: "/API/orders/property/" + orderItem.id + "/type2",
type: "GET"
});
$.when(thirdPromise).done(function (property2Results) {
orders.push(new order(orderItem, property1Results, property2Results));
});
});
});
});
return orders;
And the function call:
self.populateOrders = function (name) {
var mappedOrders = $.map(self.service.getOrders(name), function (item) {
return new Order(item)
});
self.orders(mappedOrders);
}
The new function is not working, I'm getting back from the firstPromise a wrong json with backslashes, and the returned orders object is empty.
Any idea what am I doing wrong? I spent so much time on it but couldn't figure it out.
Thanks in advance.
Nested ajax calls inside a loop is a hell to manage. You can do it like this.
Create a promise to notify the caller when the whole process is finished
Wait for all the inner ajax calls to resolve
Resolve you main promise to notify the caller
self.getOrders = function (name) {
var mainDeferred = $.Deferred();
var orders = [];
var order = function (item, type1, type2) {
var self = this;
self.order = item;
self.type1 = type1;
self.type2 = type2;
}
$.ajax({
url: "/API/orders/" + name,
type: "GET",
success: function (orderResults) {
var innerwait = [];
var mappedOrders = $.map(orderResults, function (orderItem) {
var ajax1 = $.ajax({
url: "/API/orders/property/" + orderItem.id + "/type1",
type: "GET"
});
var ajax2 = $.ajax({
url: "/API/orders/property/" + orderItem.id + "/type2",
type: "GET"
});
$.when(ajax1, ajax2).done(function (property1Results, property2Results) {
orders.push(new order(orderItem, property1Results[0], property2Results[0])))
});
innerwait.push(ajax1, ajax2);
});;
$.when.apply(null, innerwait) //make sure to wait for all ajax requests to finish
.done(function () {
mainDeferred.resolve(orders); //now that we are sure the orders array is filled, we can resolve mainDeferred with orders array
});
}
});
return mainDeferred.promise();
}
self.populateOrders = function (name) {
self.service.getOrders(name).done(function (orders) { //use .done() method to wait for the .getOrders() to resolve
var mappedOrders = $.map(orders, function (item) {
return new Order(item)
});
self.orders(mappedOrders);
});
}
In the example, note that I use $.when.apply() to wait for an array of deferreds.
A bug recently introduced in chrome 52 (august 2016) can cause this kind of behavior : answers for nested requested are ignored.
Hoppefully, it will not last long.
https://bugs.chromium.org/p/chromium/issues/detail?id=633696
Try to add cache: false
I have an array of values (myarray), that I want to iterate through and run an AJAX request on each iteration. I've put each ajax request inside another array (requests), so that I can call an alert when all AJAX requests have completed:
Like so:
var requests = [];
for (i = 0; i < myarray.length; ++i) {
requests.push($.ajax({
url: 'anotherurl?=' + myarray[i],
dataType: "JSONP",
success: function (data) {
array_of_results.push(data);
}
}));
}
$.when.apply($, requests).done(function() {
alert('complete');
});
All the results are collected in array_of_results. However due to the AJAX requests taking different lengths of time to complete, this array doesn't have the results in the original order.
Is there any way to order this array?
I hope I've made sense. I appreciate this is quite convoluted.
Have you tried the following? I think this should work. All the responses should be available, in order, in the success function of the when().
var requests = [];
for (i = 0; i < myarray.length; ++i) {
requests.push($.ajax({
url: 'anotherurl?=' + myarray[i],
dataType: "JSONP"
}));
}
$.when.apply($, requests).done(function() {
array_of_results = arguments;
alert('complete');
});
Instead of using a loop consider using recursion. Here's a complete example:
var myArray = [
"somevalue",
"some other value",
"another value"
];
var i = myArray.length;
var responses = [];
function doRequests(){
i--;
$.ajax({
url: "myurl.php",
data: {paramname: myArray[i]}
}).done(function(response){
responses.push(response);
if(i>0) doRequests();
else{
// all requests sent.. do stuff
// responses array is in order
console.log(responses);
alert("all done!");
}
});
}
You can add a custom attribute to your $.ajax object, setted to your i var.
var requests = [];
for (i = 0; i < myarray.length; ++i) {
requests.push($.ajax({
url: 'anotherurl?=' + myarray[i],
dataType: "JSONP",
myCustomIndex: i,
success: function (data) {
array_of_results[this.myCustomIndex] = data;
}
}));
}
$.when.apply($, requests).done(function() {
alert('complete');
});
JavaScript is really permisive, if you attribute a value to an array out of its bounds (higher than 0), the size of the array will be automaticaly set to the right amount.
How about using jquery.ajax call with async setting as false. This way the reaponse will be in order as requested...
Building on #Christo's answer - using arrays map function
var array_of_results = [];
var requests = myarray.map(function(item, index) {
return $.ajax({
url: 'anotherurl?=' + item,
dataType: "JSONP",
success: function (data) {
array_of_results[index] = data;
}
}
});
...
Hey all I am working on a json call that will implement Drupal's services module with json. I am using jquery's ajax function to call the function but I am getting an error stating that no parameters are being passed. When I look at the query string being posted I notice that sessid is not being passed even though its with the parameters. Below is what Im running.
// JavaScript Document
$(document).ready(function() {
function drupalConnect(src) {
$.ajax({
url: src,
type: 'POST',
data: {
method: 'system.connect'
},
success: function(data) {
return data["result"]["sessid"];
}
});
}
function getTimestamp() {
return Math.round((new Date).getTime() / 1000);
}
function randString(length) {
var chars = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz";
var randomstring = '';
for (var i = 0; i < length; i++) {
var rnum = Math.floor(Math.random() * chars.length);
randomstring += chars.substring(rnum, rnum + 1);
}
return randomstring;
}
var session_id = drupalConnect('http://localhost/drupal/services/json-rpc');
var nonce = randString(10);
var timestamp = getTimestamp();
var username = "markusgray";
var password = "Markus1990";
var key = '2ae0392e0aebbfeeddefcc962ea1924f';
var domain = 'localhost';
var hashObj = new jsSHA(timestamp + ";" + domain + ";" + nonce + ";user.login", "TEXT");
var hash = hashObj.getHMAC(key, "TEXT", "SHA-256", "HEX");
var parameters = {
hash: hash,
domain_name: domain,
domain_time_stamp: timestamp,
nonce: nonce,
sessid: session_id,
username: username,
password: password
};
var par = JSON.stringify(parameters);
$.ajax({
url: 'http://localhost/drupal/services/json-rpc',
type: 'POST',
dataType: 'json',
data: {
method: 'user.login',
params: par
},
success: function() {
}
});
});
drupalConnect doesn't return anything, also the return from the success callback is just thrown away. The best way to use the data returned from an ajax call is to use it in thee callback itself.
function drupalConnect(src){
$.ajax({
url: src,
type: 'POST',
data:{method:'system.connect'},
success: function(data){
var session_id = data["result"]["sessid"];
//use session_id here
}
});
}
It is because of the Asynchronous ajax, let me elaborate, to get the session_id you are making an ajax call. At the moment it will send the request, but it wont ensure that the session_id will be assigned at that moment. Hence when you making the second ajax call, the session_id may not be assigned for a value.
There are two workarounds for this,
One is, making the first ajax call with an option async:false and assign the value within the success call, something like
var session_id;
function drupalConnect(src) {
$.ajax({
url: src,
type: 'post',
async : false,
data: {
method: 'system.connect'
},
success: function(data) {
session_id = data["result"]["sessid"];
}
});
};
DEMO
The second one and preferred way is, use of deferred objects, something like
$.when(
// make your first ajax request
).then(function(data) {
session_id = data["result"]["sessid"];
// make your second ajax call
});
DEMO
i try to get a function return in combination with facebook api reqeust.
var g_ret = true;
function uploadImagesFbCounter(anz){
var gid='';
$("div[id ^= 'gallerydetail']").each(function (i) {
gid = this.id.split('-');
gid = parseInt(gid[1]);
})
if(gid==0) return true;
FB.api('/me', function(response) {
//console.log(response);
var uid = response.id;
if(!anz){
g_ret = $.ajax({
type: "POST",
async:false,
url: "api/gallerie_anz_speich.php",
data: "uid="+uid+"&op=get&gid="+gid
});
if(g_ret.response >= 20) {
g_ret = false;
}
} else {
g_ret = $.ajax({
type: "POST",
async:false,
url: "api/gallerie_anz_speich.php",
data: "uid="+uid+"&op=set&gid="+gid
});
//console.log(g_ret.response);
g_ret = '<span style="padding:0 5px;">Noch '+(20-g_ret.response)+'Fotos</span>';
console.log(g_ret);
}
});
return g_ret;
}
what ever I do, i get an empty response.... please help!
The API you're using is asynchronous. You can't return a value from your function like that; it's just impossible in such a situation.
Instead, write your API so that its clients pass it a callable function. Inside the Facebook API callback, you can call that function and pass it that "g_ret" string.
function uploadImagesFbCounter(anz, callback){
// ...
FB.api('/me', function(response) {
// ...
callback(g_ret);
});
}
Then when you call your function, instead of:
var result = uploadImagesFbCounter( whatever );
// ... do something with result ...
you'd do this:
uploadImagesFbCounter( whatever, function( result ) {
// ... do something with result ...
});
Getting the user information from Facebook's servers is asynchronous. This means, any code you write after FB.api() does not wait for Facebook to respond. Your browser is not blocked just to wait for Facebook's servers. This is the same concept as AJAX, which I believe you are familiar with because I see you use it in your code.
The common way to "get a return value" from an asynchronous server request is to use a callback function.
function uploadImagesFbCounter(anz, onSuccess){
var gid='';
$("div[id ^= 'gallerydetail']").each(function (i) {
gid = this.id.split('-');
gid = parseInt(gid[1]);
})
if(gid==0) return true;
FB.api('/me', function(response) {
//console.log(response);
var uid = response.id;
if(!anz){
g_ret = $.ajax({
type: "POST",
async:false,
url: "api/gallerie_anz_speich.php",
data: "uid="+uid+"&op=get&gid="+gid
});
if(g_ret.response >= 20) {
g_ret = false;
}
} else {
g_ret = $.ajax({
type: "POST",
async:false,
url: "api/gallerie_anz_speich.php",
data: "uid="+uid+"&op=set&gid="+gid
});
//console.log(g_ret.response);
g_ret = '<span style="padding:0 5px;">Noch '+(20-g_ret.response)+'Fotos</span>';
console.log(g_ret);
}
onSuccess(g_ret);
});
}
uploadImagesFbCounter(
whateverAnzIs,
function(g_ret) {
console.info(g_ret);
}
);