I have code to get data from google api.
Here is the code:
$.ajax({
url: dburl,
dataType: 'json',
async: false,
type: 'GET',
data: model,
success: function (data) {
if (data.length !== 0) {
speeddata = data;
for (var i = 0; i < speeddata.length; i++) {
path = "path=" + speeddata[i].Latitude2 + ',' + speeddata[i].Longitude2;
var googleurl = "https://roads.googleapis.com/v1/speedLimits?"
+ path + "&key=" + roadsapikey;
$.ajax({
url: googleurl,
dataType: 'json',
async: false,
type: 'GET',
success: function(data) {
speedlimits = data;
console.log(speedlimits);
for (var i = 0; i < speedlimits.length; i++) {
speedobject.push({
speedlimits: speedlimits[i].speedLimits.speedLimit
});
}
console.log(speedobject);
}
});
}
}
},
error: function () {
alert("Error");
}
});
Here is what I get in response here - speedlimits
Response
I try to take speedLimit property and push it to new object.
Like this:
for (var i = 0; i < speedlimits.length; i++) {
speedobject.push({
speedlimits: speedlimits[i].speedLimits.speedLimit
});
}
But when I show speedobject in console it is empty.
Why so? Where is my problem?
The speedlimits object looks like this:
speedlimits = { // You're looping over this (speedlimits)
speedLimits: [ // You should be looping over this (speedlimits.speedLimits[i])
{speedLimit: 50},
// ...
],
snappedPoints: []
}
You are trying to loop over the speedLimits and snappedPoints items - not the elements within speedLimits.
for (var i = 0; i < speedlimits.speedLimits.length; i++) {
speedobject.push({
speedlimits: speedlimits.speedLimits[i].speedLimit
});
}
according to the data example here the api returns an object, not an array.. so your success function would look like this.. Make sure you get the case right too.
success: function(data) {
speedlimits = data.speedLimits;
console.log(speedlimits);
for (var i = 0; i < speedlimits.length; i++) {
speedobject.push({
speedlimits: speedlimits[i].speedLimit
});
}
console.log(speedobject);
}
Related
I have an AJAX call that gets called "i" amount of times. I want to execute the rest of the code only after the last AJAX processData callback function was finished (It fills values of the .csv into an array called "lines" and I need the finished array after all iterations have finished). So far it only works by using "setTimeout()" which is not a nice solution
for (var i = 0; i < options.length; i++) {
(function(index) {
$.ajax({
type: "GET",
url: options[index] + ".csv",
dataType: "text",
success: function(data) {
processData(data, options[index], type)
}
});
})(i);
}
setTimeout(function() {
getAveragePercentages(lines);
}, 500)
You can use the JavaScript promise functionality.
Make AJAX request in the promise.
Create an array which will contains all these promise.
Promise.all will be executed after all promise get resolved.
var promiseArr = [];
for (var i = 0; i < options.length; i++) {
var promise = new Promise(function(resolve, reject) {
(function(index) {
$.ajax({
type: "GET",
url: options[index] + ".csv",
dataType: "text",
success: function(data) {
processData(data, options[index], type); resolve('outputIfany')
}
});
})(i);
});
promiseArr.push(promise);
}
Promise.all(promiseArr).then(function(values) {
getAveragePercentages(lines);
});
for (var i = 0; i < options.length; i++) {
(function (index) {
$.ajax({
type: "GET",
url: options[index] + ".csv",
dataType: "text",
success: function (data) {
processData(data, options[index], type)
}
});
counter = counter + 1;
})(i);
if (i == options.length) {
getAveragePercentages(lines);
}
}
You can do something like this.
after last Loop Success call function
var totalRec = options.length;
for(var i=0;i<options.length;i++){
(function(index){
$.ajax({
type: "GET",
url: options[index]+".csv",
dataType: "text",
success: function(data) {processData(data, options[index], type)
if(i == (totalRec-1)){
getAveragePercentages(lines);
}
}
});
})(i);
}
or
var totalRec = options.length;
for(var i=0;i<options.length;i++){
(function(index){
$.ajax({
type: "GET",
url: options[index]+".csv",
dataType: "text",
success: function(data) {processData(data, options[index], type)
}
});
})(i);
if(i == (totalRec-1)){
getAveragePercentages(lines); // gets called only when condition is true
}
}
It is not a good practice to use a setTimeOut for wait the ajax call, in my experience I've been using recursive functions for doing this, in your case you can do the following:
var counter = 0;
function main()
{
counter = 0;
doAjaxCall(counter);
}
function doAjaxCall(counter)
{
(function(index){
$.ajax({
type: "GET",
url: options[index]+".csv",
dataType: "text",
success: function(data) {
processData(data, options[index], type);
if(counter < options.length)
{
counter++;
doAjaxCall(counter); //We call the same function but with the next index
}
else
{
//The loop finished, countinue code after your for loop
}
}
});
})(i);
}
set up a counter and check it's value before calling your function
$("#counter").html("0");
for(var i=0;i<options.length;i++){
(function(index){
$.ajax({
type: "GET",
url: options[index]+".csv",
dataType: "text",
success: function(data) {
processData(data, options[index], type)
var counter = $("#counter").html();
if( counter == options.length ){
getAveragePercentages(lines);
}
$("#counter").html(counter+1);
}
});
})(i);
}
I added a function as a parameter. The AJAX calls the function when the load is completed.
function loadDoc(call_back_func) {
const xhttp = new XMLHttpRequest();
xhttp.onload = function() {
json_data = JSON.parse(this.responseText);
call_back_func();
}
xhttp.open("GET", "kanban_personal_template.json");
xhttp.send();
}
function load_call_back()
{
console.log(json_data);
}
loadDoc(load_call_back);
For the following code, the emailCnt is 50 for first iteration, I need 25 in next iteration. What is the possible way to access the variable value outside the ajax success and break the for loop execution?
var limit = 50;
var emailCnt = limit;
for (var i = 0; i < 20; i++) {
console.log(emailCnt);///this value is 50 instead I need 25
if (emailCnt < limit && i != 0) {
break;
}
setTimeout(function () {
submit_post(slNo, limit, function (output) {
slNo = output;
emailCnt = 25;
$('#load_data').html('Hello');
});
}, 1000);
}
function submit_post(slNo, limit, handleData) {
$.ajax({
type: 'POST',
async: false,
url: url,
data: { slNo: slNo, limit: limit },
success: function (data) { handleData(data); }
});
}
This successfully worked for me
var limit = 50;
var emailCnt = limit;
function submit_post(slNo, limit)
{
var result="";
$.ajax({
type: 'POST',
async: false,
url: url,
data: {slNo:slNo, limit:limit},
success: function(data) { result = data; }
});
return result;
}
for(var i=0;i<20;i++)
{
if(emailCnt < limit && i != 0)
{
break;
}
setTimeout(function () {
var output = submit_post(slNo, limit);
slNo = output;
emailCnt = 25;
$('#load_data').html('Hello');
}, 1000);
}
I have a program which calls a function in javascript with 1 o more requests to 1 servlet, I want to execute request after request and get the response after each exucution, to make this I have 1 function, but it only shows the result after all requests have been executed.
function cmd(args) {
width = 0;
var res = args.split('\n');
var largo = res.length;
var progressLength = 100 / largo;
for (var i = 0; i < largo; i++)
{
if (res[i] == 'desconectar')
{
desconectar();
break;
}
else
{
executeCMD(res[i]);
}
}
}
function executeCMD(args)
{
$.ajax({
type: "POST",
url: 'Controlador',
data: {cmd: args, operacion: 1},
success: function (response) {
document.getElementById('respuesta').value = document.getElementById('respuesta').value + response;
},
dataType: 'text',
async: false
});
}
If I add window.alert(response); inside success field it shows the progress step by step and works fine, but it show alerts which I don't want.
This is I want http://imgur.com/a/9nclR but I'm getting only last picture.
The solution if anyone is intersting was using a recursive function as next:
function cmd(args) {
width = 0;
move(0);
var res = args.split('\n');
var largo = res.length;
var valInit = 0;
if (largo > valInit)
{
executeCMD(res, valInit);
}
}
function executeCMD(args, i)
{
$(document).ready(function () {
$.ajax({
type: "POST",
url: 'ControladorServlet',
data: {cmd: args[i], operacion: 1, ticket: ticket, iddispositivo: sesion},
success: function (response) {
var textarea = document.getElementById('respuesta');
var res = response.trim().split('\n');
if(error){//dc}
else
{
document.getElementById('respuesta').value = document.getElementById('respuesta').value + response.trim() + "\n\n";
var valor = (100) * (i + 1) / args.length;
move(valor);
if (i + 1 < args.length)
{
executeCMD(args, i + 1);
}
}
},
dataType: 'text'
});
});
}
I have script in A.js like this:
function sinkronMyDB(){
sinkronDB();
var u_name = window.localStorage.getItem('uname');
if(dataSync.length !== 0){ // <-- line 4
var dataSinkronItems = [];
for (var i = 0; i<dataSync.length; i++) {
dataSinkronItems[i] = dataSync[i];
console.log('dataSync('+i+') = '+dataSync[i]);
};
$.ajax({
url:'http://qrkonfirmasi.16mb.com/delivery/update.php',
data: {data : dataSinkronItems, username: u_name},
type:'post',
async:'false',
dataType: 'json',
beforeSend:function(){
$.mobile.loading('show',{theme:"a",text:"Update...",textonly:true,textVisible:true});
},
complete:function(){
$.mobile.loading('hide');
},
success:function(result){
if (result.status===true) {
dataBaru = [];
idBaru = [];
for (i=0; i<dataBaru.length; i++){
dataBaru[i] = result.dataBaru[i];
idBaru[i] = result.id[i];
}
sinkronUpd();
console.log('Database update success.');
} else{
console.log('Tidak ada pengiriman baru.');
}
},
error:function(request,error){
alert('Koneksi error. Silahkan coba beberapa saat lagi!');
}
});
}else alert('Belum ada barang yang terkirim');
}
function sinkronDB() is in another Script file. lets call it B.js. the script content is like this:
function sinkronDB(){
db.transaction(sinkronQuery,errorCB);
}
function sinkronQuery(tx){
tx.executeSql("SELECT * FROM data_pengiriman WHERE Status = 'Terkirim'",[],successSelect);
}
function successSelect(tx,result){
var len = result.rows.length;
dataSync = [];
for (var i=0; i<len; i++){
dataSync[i] = result.rows.item(i).id_pengiriman;
console.log('dataSync['+i+'] = '+dataSync[i]);
}
}
In console log it's say error:
Uncaught ReferenceError: dataSync is not defined at file A.js line 4.
I tried check it with jshint and no error.
Can anyone help me solve it, please!
The problem is sinkronDB is asynchronous, so the if statement is evaluated before sinkronDB is completed
So you need to use a callback to handle the response like
function sinkronDB(callback) {
db.transaction(function (tx) {
sinkronQuery(tx, callback)
}, errorCB);
}
function sinkronQuery(tx, callback) {
tx.executeSql("SELECT * FROM data_pengiriman WHERE Status = 'Terkirim'", [], function (tx, result) {
successSelect(tx, result, callback);
});
}
function successSelect(tx, result, callback) {
var len = result.rows.length;
var dataSync = [];
for (var i = 0; i < len; i++) {
dataSync[i] = result.rows.item(i).id_pengiriman;
console.log('dataSync[' + i + '] = ' + dataSync[i]);
}
callback(dataSync)
}
then
function sinkronMyDB() {
sinkronDB(function (dataSync) {
var u_name = window.localStorage.getItem('uname');
if (dataSync.length !== 0) { // <-- line 4
var dataSinkronItems = [];
for (var i = 0; i < dataSync.length; i++) {
dataSinkronItems[i] = dataSync[i];
console.log('dataSync(' + i + ') = ' + dataSync[i]);
};
$.ajax({
url: 'http://qrkonfirmasi.16mb.com/delivery/update.php',
data: {
data: dataSinkronItems,
username: u_name
},
type: 'post',
async: 'false',
dataType: 'json',
beforeSend: function () {
$.mobile.loading('show', {
theme: "a",
text: "Update...",
textonly: true,
textVisible: true
});
},
complete: function () {
$.mobile.loading('hide');
},
success: function (result) {
if (result.status === true) {
dataBaru = [];
idBaru = [];
for (i = 0; i < dataBaru.length; i++) {
dataBaru[i] = result.dataBaru[i];
idBaru[i] = result.id[i];
}
sinkronUpd();
console.log('Database update success.');
} else {
console.log('Tidak ada pengiriman baru.');
}
},
error: function (request, error) {
alert('Koneksi error. Silahkan coba beberapa saat lagi!');
}
});
} else alert('Belum ada barang yang terkirim');
});
}
As the error message says, you have not defined dataSync.
Define it, var dataSync = []; and push whatever you need to it.
You have defined dataSync inside successSelect(tx,result) method, and it is not a global variable. sinkronMyDB() method has no access to it.
If you want to make it a global array, put var dataSync = [] outside the functions, and make sure successSelect(tx,result) method is executed before sinkronMyDB() method.
I am trying to call a method after all ajax calls gets completed but some reason the method id getting triggered before one of the ajax call is getting completed. i tried to keep the method in ajax complete section and using $.when() and async:false but i am getting same result. I don't know if its because i am using jsonp ?
My jquery version is 1.11.0
Below is my code
function getBBTrending() {
bbProductD = [];
jQuery.ajax({
type: "GET",
url: "crazycalls/getbbtrending.php",
// cache must be true
cache: true,
crossDomain: true,
success: function (data) {
bbTrending = data.results;
for (var i = 0; i < 4; i++) {
getProductdetails(bbTrending[i].productLink);
}
},
dataType: 'json'
});
}
function getProductdetails(pLink) {
jQuery.ajax({
type: "GET",
url: pLink,
// cache must be true
cache: true,
crossDomain: true,
success: function (data) {
pushArray(bbProductD, data);
},
dataType: 'jsonp'
});
}
function pushArray(array1,data1)
{
array1.push(data1);
}
// this function is executing before pushArray(array1,data1)
jQuery( document ).ajaxStop(function() {
displayProducts(bbProductD);
})
function displayProducts(bbProductD)
{
jQuery("#bbButtongroup").show();
var rProducts = bbProductD;
var rating;
var html = ['<div class="row">']
for (var i = 0; i < rProducts.length; i++)
{
var entry = rProducts[i];
var title = entry.name
var Tnail = entry.image;
var sPrice = entry.salePrice;
var rPrice = entry.regularPrice;
var hcode = '<div class="col-sm-6 col-md-4"><div class="thumbnail"><img style="height: 200px; width: 100%; display: block;" src=\" '+ Tnail + '\" alt="..."><div class="caption"><h3 style="font-size: 14px;">'+ title +'</h3><p><span class="label label-info"> Regular Price : '+ rPrice +'</span></p><p><span style="float: right;" class="label label-info">Sale Price :'+ sPrice +'</span></p><p>BuyView</p></div></div></div>';
html.push(hcode);
}
html.push('</div>');
document.getElementById('pContainer').innerHTML = html.join('');
}
this is how i added using $.when
jQuery.when( { getBBTrending(),getProductdetails()}).done(function() {
displayProducts(bbProductD);
});
any advice?
The asynchronous way, using async library
function getBBTrending() {
bbProductD = [];
jQuery.ajax({
//stuff...
success: function (data) {
bbTrending = data.results;
async.each(bbTrending, function(element, callback){
getProductdetails(element.productLink, callback);
}, function(err){
displayProducts(bbProductD);
});
},
});
}
function getProductdetails(pLink, callback) {
jQuery.ajax({
//stuff
success: function (data) {
pushArray(bbProductD, data);
callback(null);
},
});
}
The promises way, using jQuery.Deferred and jQuery.when
function getBBTrending() {
bbProductD = [];
jQuery.ajax({
//stuff...
success: function (data) {
bbTrending = data.results;
var promises = [];
for (var i = 0; i < bbTrending.length; i++) {
var promise = getProductdetails(bbTrending[i].productLink);
promises.push(promise);
}
jQuery.when.apply(jQuery, promises).then(function(){
displayProducts(bbProductD);
});
},
});
}
function getProductdetails(pLink) {
var promise = jQuery.Deferred();
jQuery.ajax({
//stuff
success: function (data) {
pushArray(bbProductD, data);
promise.resolve();
},
});
return promise;
}
The dirty way. I do not recommend this solution, it has many flaws. Try to use libraries when you need to do asynchronous stuff in order to keep your code maintainable.
var queriesCount, finishedQueriesCount;
function getBBTrending() {
bbProductD = [];
jQuery.ajax({
//stuff...
success: function (data) {
bbTrending = data.results;
queriesCount = 0;
finishedQueriesCount = 0;
for (var i = 0; i < bbTrending.length; i++) {
getProductdetails(bbTrending[i].productLink);
}
},
});
}
function getProductdetails(pLink) {
queriesCount++;
jQuery.ajax({
//stuff
success: function (data) {
pushArray(bbProductD, data);
finishedQueriesCount++;
if(queriesCount == finishedQueriesCount) {
displayProducts(bbProductD);
}
},
});
}
In each case, I pleaced the part of your code that is not significant for the answer by //stuff
Warning This answer has no error handling, it will fail (never call displayProducts(bbProductD);) if you have an ajax error.