How to get whole data out of callback function in javascript - javascript

I have written following function which takes a json data from a url.
function getWeatherDataForCities(cityArray){
var arrAllrecords = [];
var toDaysTimestamp = Math.round((new Date()).getTime() / 1000) - (24*60*60);
for(var i in cityArray){
for(var j=1; j<=2; j++){
var jsonurl = "http://api.openweathermap.org/data/2.5/history/city?q="+cityArray[i]+"&dt="+toDaysTimestamp;
$.ajax({
url: jsonurl,
dataType: "jsonp",
mimeType: "textPlain",
crossDomain: true,
contentType: "application/json; charset=utf-8",
success: function(data){
arrAllrecords[j]["cityName"] = data.list[0].city.name;
arrAllrecords[j]["weather"] = data.list[0].weather[0].description;
} });
toDaysTimestamp = toDaysTimestamp - (24*60*60);
}
}
return arrAllrecords; //returning arrAllrecords
}
$(document ).ready(function() {
var cityArray = new Array();
cityArray[0] = "pune";
var arrAllRecords = getWeatherDataForCities(cityArray);
//Print All records returned by getWeatherDataForCities(cityArray);
});
I have written some comments in above code.I have called getWeatherDataForCities function which returns all records from url.I have declared getWeatherDataForCities array in function.I want to add all returned records in that array.I have tried as above but nothing is getting into array.
In console showing j and arrAllrecords are undefined.
How to get all records in array from callback function?
you response will be highly appreciated

Your getWeatherDataForCities function won't return anything because ajax operations are asynchronous. You need to use a callback for that.
Modify your function to accept a callback function:
function getWeatherDataForCities(cityArray, callback){
var arrAllrecords = [];
var toDaysTimestamp = Math.round((new Date()).getTime() / 1000) - (24*60*60);
for(var i in cityArray){
for(var j=1; j<=2; j++){
var jsonurl = "http://api.openweathermap.org/data/2.5/history/city?q="+cityArray[i]+"&dt="+toDaysTimestamp;
$.ajax({
url: jsonurl,
dataType: "jsonp",
mimeType: "textPlain",
crossDomain: true,
contentType: "application/json; charset=utf-8",
success: function(data){
arrAllrecords[j]["cityName"] = data.list[0].city.name;
arrAllrecords[j]["weather"] = data.list[0].weather[0].description;
// call the callback here
callback(arrAllrecords);
}
});
toDaysTimestamp = toDaysTimestamp - (24*60*60);
}
}
}
And use it like this:
$(document ).ready(function() {
var cityArray = new Array();
cityArray[0] = "pune";
getWeatherDataForCities(cityArray, function(arrAllrecords) {
// Do something with your data
});
});

You are trying to use the empty array. When fetching the values it will always return you undefined.
var arrAllrecords = [];
arrAllrecords[2]; //undefined
arrAllrecords[2]["cityname"]; //undefined
Better you should use array of objects.
I don't know why you have used variable j. The below code works for me.
var arrAllrecords = [];
function getWeatherDataForCities(cityArray){
var toDaysTimestamp = Math.round((new Date()).getTime() / 1000) - (24*60*60);
for(var i in cityArray){
var jsonurl = "http://api.openweathermap.org/data/2.5/history/city?q="+cityArray[i]+"&dt="+toDaysTimestamp;
$.ajax({
url: jsonurl,
dataType: "jsonp",
mimeType: "textPlain",
crossDomain: true,
contentType: "application/json; charset=utf-8",
success: function(data){
arrAllrecords.push({
"cityName" : data.list[0].city.name,
"weather" : data.list[0].weather[0].description
});
if(arrAllrecords.length === cityArray.length) {
callback(arrAllrecords);
}
} });
}
}
function callback(arrAllrecords) {
console.log(arrAllrecords);
}
$(document).ready(function() {
var cityArray = new Array();
cityArray[0] = "pune";
cityArray[1] = "mumbai";
cityArray[2] = "delhi";
getWeatherDataForCities(cityArray);
});

Related

JQuery Ajax loop delay

i am trying to make a delay in my ajax data so the loop become a little bit slower !
and here is my code
$(document).ready(function (){
$('#button').click(function(){
$('#hide').show();
var data = $('#textarea').val();
var arrayOfLines = data.split("\n");
var track = JSON.stringify(arrayOfLines);
var item = "";
var lines = $('#textarea').val().split('\n');
here is the loop
for (var i = 0; i < lines.length; i++) {
item = lines[i];
$.ajax({
type: 'GET',
url: 'cookie.php',
dataType: 'html',
data: 'data=' + item+'&cookie='+track,
success: function(msg){
$('#results').append(msg);
}
});
}
});
Using recursion, you could put in a function sendToServer and pass through the array lines, starting index 0. The function will run from 0 to lines.length. This way you won't DDOS your server :)
If you really need some kind of arbitrary delay, you can include a timeout on the sendToServer function call - in the example it is set to 5 seconds.
var sendToServer = function(lines, index){
if (index > lines.length) return; // guard condition
item = lines[index];
if (item.trim().length != 0){
$.ajax({
type: 'GET',
url: 'cookie.php',
dataType: 'html',
data: 'data=' + item+'&cookie='+track,
success: function(msg){
$('#results').append(msg);
setTimeout(
function () { sendToServer(lines, index+1); },
5000 // delay in ms
);
}
});
}
else { sendToServer(lines, index+1); }
};
sendToServer(lines, 0);
Don't send request to server in for loop. It can take down the server. Instead of what you did , you can do this :
for (var i = 0; i < lines.length; i++) {
item = lines[i];
}
$.ajax({
type: 'GET',
url: 'cookie.php',
dataType: 'html',
data: 'data=' + item+'&cookie='+track,
success: function(msg){
$('#results').append(msg);
}
});
Use like this:
var timeDelay = 5000;
setTimeout(Function, timeDelay);

Ajax inside a While Loop Crashes in Javascript

I want a while loop that iterates if the amount paid is greater than zero. But running the code crashes the browser.
var amount = Number($('#payment1').val());
while (amount > 0){
$.ajax({
type: "POST",
url: baseurl + "collection/getSingleAmort",
data: {'contractid':contractID},
success: function(result){
var data = jQuery.parseJSON(result);
console.log(data);
var amortizationAmount = Number(data['amortization'][i].amortization_amount);
amount = amount -amortizationAmount;
},
error: function (errorThrown){
//toastr.error('Error!', 'Operation Done');
//console.log(errorThrown);
}
});
}
function xyz(amount){
$.ajax({
type: "POST",
url: baseurl + "collection/getSingleAmort",
data: {'contractid':contractID},
success: function(result){
var data = jQuery.parseJSON(result);
console.log(data);
var amortizationAmount = Number(data['amortization'][i].amortization_amount);
amount = amount -amortizationAmount;
if(amount>0)
xyz(amount);
},
error: function (errorThrown){
//toastr.error('Error!', 'Operation Done');
//console.log(errorThrown);
}
});
}
var amount = Number($('#payment1').val());
xyz(amount);
Try something like this. Instead of looping recursion is used.
Add async:false
var amount = Number($('#payment1').val());
while (amount > 0){
$.ajax({
type: "POST",
url: baseurl + "collection/getSingleAmort",
data: {'contractid':contractID},
async:false,
success: function(result){
var data = jQuery.parseJSON(result);
console.log(data);
var amortizationAmount = Number(data['amortization'][i].amortization_amount);
amount = amount -amortizationAmount;
},
error: function (errorThrown){
//toastr.error('Error!', 'Operation Done');
//console.log(errorThrown);
}
});
}

jquery not being called when switched from ajax

I had an ajax function, that needed to be converted to being called with Jquery for wordpress - but now the function doesn't get called?
function getCategories()
{
alert('getCategories test');
var fData = new Object();
fData.val = '';
jQuery(document).ready(
{
type: "POST",
contentType: "application/json; charset=utf-8",
url: "php_scripts/getdeals_php.php",
data: '{"action":"GetCats", "fData":' + JSON.stringify(fData) + '}',
dataType: "json",
success: function (msg)
{
alert('Success');
var offerList = msg;
var Cats = document.getElementById('CategoriesSelect');
document.getElementById("CategoriesSelect").options.length = 0;
var optn = document.createElement('option');
optn.text = "Select Category";
optn.value = "Select Category";
Cats.add(optn);
for(var i=0;i<offerList.length;i++)
{
var optn = document.createElement('option');
optn.text = offerList[i];
optn.value = offerList[i];
Cats.add(optn);
}
},
error: function (xhr, ajaxOptions, thrownError)
{
alert("ERROR:" + xhr.responseText+" - "+thrownError);
}
});
}
I get my 'getCategories test' alert but I don't get the 'success' or the 'error' alert
So I do not think the jquery is running.
Before I started integrating this with wordpress I was using ajax like this
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "php_scripts/getdeals_php.php",
data: '{"action":"GetCats", "fData":' + JSON.stringify(fData) + '}',
dataType: "json",
success: function (msg)
{
$('#loadingmessage').hide();
var offerList = msg;
var Cats = document.getElementById('CategoriesSelect');
document.getElementById("CategoriesSelect").options.length = 0;
var optn = document.createElement('option');
optn.text = "Select Category";
optn.value = "Select Category";
Cats.add(optn);
for(var i=0;i<offerList.length;i++)
{
var optn = document.createElement('option');
optn.text = offerList[i];
optn.value = offerList[i];
Cats.add(optn);
}
},
error: function (xhr, ajaxOptions, thrownError)
{
alert("ERROR:" + xhr.responseText+" - "+thrownError);
}
});
I would get an erorr that ajax was unknown, and it appears I should be using jquery for this instead...?
I get no errors in the console
Well, there are some different method for calling Ajax in WP. For instance, one way would be like
FOR JS Piece
jQuery(document).ready(function($) {
// We'll pass this variable to the PHP function example_ajax_request
var fruit = 'Banana';
// This does the ajax request
$.ajax({
url: ajaxurl,
data: {
'action':'example_ajax_request',
'fruit' : fruit
},
success:function(data) {
// This outputs the result of the ajax request
console.log(data);
},
error: function(errorThrown){
console.log(errorThrown);
}
});
});
and PHP piece
function example_ajax_request() {
// The $_REQUEST contains all the data sent via ajax
if ( isset($_REQUEST) ) {
$fruit = $_REQUEST['fruit'];
// Let's take the data that was sent and do something with it
if ( $fruit == 'Banana' ) {
$fruit = 'Apple';
}
// Now we'll return it to the javascript function
// Anything outputted will be returned in the response
echo $fruit;
// If you're debugging, it might be useful to see what was sent in the $_REQUEST
// print_r($_REQUEST);
}
// Always die in functions echoing ajax content
die();
}
add_action( 'wp_ajax_example_ajax_request', 'example_ajax_request' );
// If you wanted to also use the function for non-logged in users (in a theme for example)
// add_action( 'wp_ajax_nopriv_example_ajax_request', 'example_ajax_request' );
Thanks to wptheming
In your case, first try to follow template for JS part and secondly always remember in WP to prevent conflict, you must always use
jQuery(document).ready(function($) {
// You JS functions
});
So I tried to modify your code now on the fly, hope it works for you.
jQuery(document).ready(function($) {
var fData = new Object();
fData.val = '';
$.ajax({
type: "POST",
contentType: "application/json; charset=utf-8",
url: "php_scripts/getdeals_php.php",
data: '{"action":"GetCats", "fData":' + JSON.stringify(fData) + '}',
dataType: "json",
success: function (msg)
{
$('#loadingmessage').hide();
var offerList = msg;
var Cats = document.getElementById('CategoriesSelect');
document.getElementById("CategoriesSelect").options.length = 0;
var optn = document.createElement('option');
optn.text = "Select Category";
optn.value = "Select Category";
Cats.add(optn);
for(var i=0;i<offerList.length;i++)
{
var optn = document.createElement('option');
optn.text = offerList[i];
optn.value = offerList[i];
Cats.add(optn);
}
},
error: function (xhr, ajaxOptions, thrownError)
{
alert("ERROR:" + xhr.responseText+" - "+thrownError);
}
});
});
RF: AJAX in Plugins ( WP DOCS )

Angular ng-grid : how to load multiple api data?

I have a 'ng-grid' table that have 2 types of data source. One is from my database using a function called getContributors(), and another one is from a list of api(s).
The getContributors function is like the default function in the ng-grid tutorial.
function getContributors() {
var deferred = $q.defer();
$http.get(contributorsFile)
.then(function(result) {
contributors = result.data;
deferred.resolve(contributors);
}, function(error) {
deferred.reject(error);
});
return deferred.promise;
}
My method for loading the multiple api data is to load the database data first, and then after all the database data is all loaded it will make a request to the api using a parameter from the database data
var ajax_wait_count = 0;
gridService.getContributors().then(function(data) {
// Looping each data with angular.forEach()
angular.forEach(data, function(value, key){
var this_uid = value['uid'];
// if(ajax_wait_count==0)
// {
$timeout(function(){
$.ajax({
url: "<?php echo $glob_base_url; ?>api/getrank.php",
type: 'POST',
data: { id: this_uid },
dataType: 'json', // Notice! JSONP <-- P (lowercase)
success: function (json) {
// do stuff with json (in this case an array)
// json = jQuery.parseJSON(json);
data[key]['ranked_tier'] = json;
// console.log(json);
},
error: function () {
// alert("Error");
}
});
$.ajax({
url: "<?php echo $glob_base_url; ?>api/getlevel.php",
type: 'POST',
data: { id: this_uid },
dataType: 'json', // Notice! JSONP <-- P (lowercase)
success: function (json) {
// do stuff with json (in this case an array)
// json = jQuery.parseJSON(json);
data[key]['level'] = json['level'];
// console.log(json);
},
error: function () {
// alert("Error");
}
});
$.ajax({
url: "<?php echo $glob_base_url; ?>api/getsummonercreate.php",
type: 'POST',
data: { id: this_uid },
dataType: 'json', // Notice! JSONP <-- P (lowercase)
success: function (json) {
// do stuff with json (in this case an array)
// json = jQuery.parseJSON(json);
if (json != 0) {
var date_c = json[0]['create_date'];
date_c = date_c.replace(' ', 'T');
new_date = new Date(date_c);
// console.log(json);
var datestring = new_date.format("yyyy-mm-dd HH:MM:ss");
data[key]['summoner_create_date'] = datestring;
}
else if (json == 0) {
data[key]['summoner_create_date'] = "";
}
},
error: function () {
// alert("Error");
}
});
$.ajax({
url: "<?php echo $glob_base_url; ?>api/getlastplayed.php",
type: 'POST',
data: { id: this_uid },
dataType: 'json', // Notice! JSONP <-- P (lowercase)
success: function (json) {
// do stuff with json (in this case an array)
// json = jQuery.parseJSON(json);
if (json != "null" && json != null) {
var datedatas = json;
var datearray = [];
var thedatestr = "";
var loopidx = 1;
now_date = new Date();
now_date.setHours(0);
now_date.setMinutes(0);
now_date.setSeconds(0);
now_date.setDate(now_date.getDate() - 2);
next_date = new Date();
next_date.setHours(23);
next_date.setMinutes(59);
next_date.setSeconds(59);
// next_date.setDate(next_date.getDate());
angular.forEach(datedatas, function (value3, key3) {
datearray[key3] = parseInt(value3['createDate']);
});
datearray.sort();
datearray.reverse();
var count_played_today = 0;
angular.forEach(datearray, function (value2, key2) {
if (loopidx == 1) {
thedatestr = value2;
}
date_compare = new Date(parseInt(value2));
if (date_compare.getTime() >= now_date.getTime() && date_compare.getTime() < next_date.getTime()) {
count_played_today++;
}
loopidx++;
});
// var date_c = json[0]['create_date'];
// date_c = date_c.replace(' ','T');
var dateinsert = parseInt(thedatestr);
new_date = new Date(dateinsert);
// console.log(json);
var datestring = new_date.format("yyyy-mm-dd HH:MM:ss");
data[key]['last_played_date'] = datestring;
this_date = new Date();
date_diff = dateDiff(new_date.toString(), this_date.toString());
data[key]['last_played_date_qty'] = date_diff.d + " days " + date_diff.h + " hours " + date_diff.m + " minutes";
data[key]['count_played'] = count_played_today;
}
else if (json == "null" || json == null) {
data[key]['last_played_date'] = "";
data[key]['last_played_date_qty'] = "";
data[key]['count_played'] = 0;
}
},
error: function () {
// alert("Error");
}
});
},1500);
ajax_wait_count=0;
// }
ajax_wait_count++;
});
$scope.myData = data;
});
Now, the problem that emerges is :
The loading time for the api data is very long, and because of ajax asynchronous request, I can't make a loading function to delay the data
It appends the api data after the database data, which sometimes confuses the user whether the data is loaded or not
Sometimes in Chrome, the request is too much and it returns "err_insufficient_resources"
My question is,
Can my method of loading the api data be changed so it will make the loading time much faster and more efficient?
To make users less confused about the high amount of data, how can I make the progressbar (angular progress bar) wait for the database data + the api (AJAX) data?
Thank you in advance

moving data to $.ajax's out?

I want to move "data" variable to out of success function for other operation.
$("a[class=note]").click(function( evt ){
var note = $(this).attr("value");
var preid = $(this).attr("id");
$.ajax({
type: 'GET',
url: 'style/ajax.php',
data: 'do=note&value=' + note + '&preid=' + preid,
success: function(data)
{
alert(data);
}
});
});
For example php have Global pharase..
global var(which is the worse solution, but this is what you asked for):
$("a.note").click(function( evt ){
var note = $(this).attr("value");
var preid = $(this).attr("id");
$.ajax({
type: 'GET',
url: 'style/ajax.php',
data: 'do=note&value=' + note + '&preid=' + preid,
success: function(data)
{
window.data = data;
alert(data);
}
});
});
global variable are dangerous, Maybe variable outside the success scope is enough?
Var outside the success callback:
$("a.note").click(function( evt ){
var note = $(this).attr("value");
var preid = $(this).attr("id");
var dataFromServer = null;
$.ajax({
type: 'GET',
url: 'style/ajax.php',
data: 'do=note&value=' + note + '&preid=' + preid,
success: function(data)
{
dataFromServer = data;
alert(data);
}
});
});
Last option is to have a hidden input that will store the data;
success: function(data)
{
$('#hiddenFieldId').val(data);
alert(data);
}
Things to notice:
I changed your selector from a[class=note] to a.note which is better.
success is a callback which means it will not be fired until the response reach the client, until then your global\outside var\hidden input value will be null. if you don't want the ajax to be asynchronous you can define it in the options like this:
$.ajax({
async: false, // <---
type: 'GET',
url: 'style/ajax.php',
data: 'do=note&value=' + note + '&preid=' + preid,
success: function(data)
{
dataFromServer = data;
alert(data);
}
});
$("a[class=note]").click(function( evt ){
var note = $(this).attr("value");
var preid = $(this).attr("id");
$.ajax({
type: 'GET',
url: 'style/ajax.php',
data: 'do=note&value=' + note + '&preid=' + preid,
success: function(data)
{
window.data = data;
}
});
});
Of course you can't use it until the callback fires.
Define var data = null; above all your code, that would be global variable. After that, rename argument for process function and in function body window.data = response;.
EDIT
You can define function to trigger data changes, for example:
var data = null;
function setGlobal(v) {
window.data = v;
alert(window.data);
}
$("a[class=note]").click(function( evt ){
var note = $(this).attr("value");
var preid = $(this).attr("id");
$.ajax({
type: 'GET',
url: 'style/ajax.php',
data: 'do=note&value=' + note + '&preid=' + preid,
success: function(data){
setGlobal(data);
}
});
});
Try it...

Categories