JavaScript jquery.ajax in success after loop nothing working - javascript

I need to pass some values to other function in Javascript. I have got the values from another PHP file but I can not pass it to any other Javascript Function. Nothing is working in SUCCESS after FOR LOOP. Need Help?
url1 = 'http://localhost:81/Dashboard/admin/inc/dashboard.php';
$.ajax({
url: url1,
type: "POST",
dataType: "json",
success: function(data)
{
for(var i = 0; i <= 11; i++)
{
Month = data[i].Month;
Sales = data[i].Sales;
if (i == 0) global_ij = "[" + Month + "," + Sales + "]";
else global_ij = global_ij + "," + "[" + Month + "," + Sales + "]";
}
alert ("hello"); // this alert is also not working
}
});

looks like your php is returning 8 elements and in your success method your loop iterates over 11 items, causing error.
I separated the success function and tried it with the data you posted and replaced the 11 in the loop with data.length. take a look at the following codepen:
http://codepen.io/anon/pen/OyXzGb?editors=011
note that I added
var Month;
var Sales;
to keep those temporary variables inside the scope of the function.
You might need to check Data to see if it is a proper array, to catch errors. before this line:
for(var i = 0; i < data.length; i++)
final output and something to try out:
var global_ij="";
function processData(data) {
var Month;
var Sales;
for(var i = 0; i < data.length; i++)
{
Month = data[i].Month;
Sales = data[i].Sales;
if (i == 0) global_ij = "[" + Month + "," + Sales + "]";
else global_ij = global_ij + "," + "[" + Month + "," + Sales + "]";
console.log(global_ij);
}
return global_ij;
}
try out this function without the ajax first:
processData([{"Month":"1","Year":"2015","Sales":"19746.81"},
{"Month":"2","Year":"2015","Sales":"17902.26"},{"Month":"3","Year":"2015","Sales":"19223.84"},{"Month":"4","Year":"2015","Sales":"18840.88"},{"Month":"5","Year":"2015","Sales":"19889.97"},{"Month":"6","Year":"2015","Sales":"18509.85"},{"Month":"7","Year":"2015","Sales":"1886.81"},{"Month":"8","Year":"2015","Sales":"1740.34"}]);
you might want to use .done()

That's because you are performing an asynchronous AJAX operation. In other words, the assignments on variables Month, Sale, global_ij that you are making are only available in that particular success function's scope and NOT outside of it.
One workaround for you is to add async: false to your AJAX call which will force it out of asynchronous behavior, therefore allowing you to make the values assigned to those variables available to all the remaining block of code:
$.ajax({
url: url1,
async: false,
type: "POST",
dataType: "json",
success: function(data)
{
for(var i = 0; i <= 11; i++)
{
Month = data[i].Month;
Sales = data[i].Sales;
if (i == 0) global_ij = "[" + Month + "," + Sales + "]";
else global_ij = global_ij + "," + "[" + Month + "," + Sales + "]";
}
}
});
jQuery's AJAX calls return promise objects which enforce methods such as .done(), .fail(), etc.
On the other hand, you could also get a promise from the AJAX call (which you can pass around anywhere in your Javascript code) and when the promise gets resolved invoke it's .done() handler.
var promise = $.ajax({/* settings */});
/* --- */
// promise passed to some other block of code
promise.done(function(){
//execute the block of code after the promise was resolved
});
Read more about this here.

The response from the PHP file is:
[
{"Month":"1","Year":"2015","Sales":"19746.81"}, // 1
{"Month":"2","Year":"2015","Sale‌​s":"17902.26"}, // 2
{"Month":"3","Year":"2015","Sales":"19223.84"}, // 3
{"Month":"4","Year"‌​:"2015","Sales":"18840.88"}, // 4
{"Month":"5","Year":"2015","Sales":"19889.97"}, // 5
{"Mont‌​h":"6","Year":"2015","Sales":"18509.85"}, // 6
{"Month":"7","Year":"2015","Sales":"1886‌​.81"}, // 7
{"Month":"8","Year":"2015","Sales":"1740.34"} // 8
]
Yet you are looping
for(var i = 0; i <= 11; i++)
So when i >= 8, data[i].Month will throw an "data[i] is undefined" error.
Simply use the .length property instead:
for(var i = 0; i < data.length; i++)
Example Fiddle

Modify your code to declare the gloabla_ij variable outside the loop. somehting like below..
var global_ij='0';
url1 = 'http://localhost:81/Dashboard/admin/inc/dashboard.php';
$.ajax({
url: url1,
type: "POST",
dataType: "json",
success: function(data)
{
for(var i = 0; i <= 11; i++)
{
Month = data[i].Month;
Sales = data[i].Sales;
if (i == 0) global_ij = "[" + Month + "," + Sales + "]";
else global_ij = global_ij + "," + "[" + Month + "," + Sales + "]";
}
}
});

If you declare the var at the top of the file, it can be used by any function within the file:
var global_ij; // declare variable in global scope of module/file
$.ajax({
url: 'http://localhost:81/Dashboard/admin/inc/dashboard.php',
type: "POST",
dataType: "json",
success: function(data) {
var i, month, sales, len = data.length;
for(i=0; i<=len; i++) {
month = data[i].Month;
sales = data[i].Sales;
if (i===0) global_ij = "[" + month + "," + sales + "]";
else global_ij = global_ij + "," + "[" + month + "," + sales + "]";
}
doSomething(); // can now call function after loop finished
}
});
func doSomething() {
// global_ij is now populated
}

Related

Don't write comma after last element in for loop

I have function that gets data from a database and displays it in the view:
function GetUsers() {
let url = "/Home/GetUsers";
$.ajax({
type: 'GET',
url: url,
dataType: 'json',
success: function(data) {
console.dir(data);
for (var i = 0; i < data.length; ++i) {
$('#taskresult3').append('<b>' + data[i].UserName + "-" + data[i].RoleName + "," + '</b>');
}
}
});
}
It displays it with comma, but after the last Username+RoleName it adds a
comma too. As I understood I need to get last iteration of for loop? How I can fix this problem?
I usually make a little trick for this cases:
var separator = "";
for (var i = 0; i < data.length; ++i) {
$('#taskresult3').append(separator + '<b>' + data[i].UserName + "-" + data[i].RoleName + '</b>');
separator = ",";
}
Simply check if the current element is the last element and if so, don't add the comma:
$('#taskresult3').append('<b>'+ data[i].UserName +"-"+ data[i].RoleName + (i === data.length - 1 ? "" : ",")+'</b>');
Dont add comma for the last element.
for (var i = 0; i < data.length; ++i) {
if (i === data.length - 1)
$('#taskresult3').append('<b>' + data[i].UserName + "-" + data[i].RoleName '</b>');
else
$('#taskresult3').append('<b>' + data[i].UserName + "-" + data[i].RoleName + "," + '</b>');
}
There is one more approach using .join() on arrays
var _html = [];
for (var i = 0; i < data.length; ++i) {
var _inhtml = '<b>' + data[i].UserName + "-" + data[i].RoleName+'</b>';
_html.push(_inhtml);
}
$('#taskresult3').append(_inhtml.join(","));
With this you can cut down the overhead of manipulating DOM multiple times.
You could use map and join to solve this, instead of using a loop.
$('#taskresult3').append('<b>' + data.map(item => item.UserName + "-" + item.RoleName).join(',</b><b>') + '</b>')
map would convert the array, to an array of item.UserName + "-" + item.RoleName, this array then would be joined together using ,</b><b> and the last part that is then missing is the first <b> and the last </b>
You can avoid the comma and improve your logic by building the HTML in an array, then using join() to display it, like this:
success: function(data) {
var html = data.map(function(item) {
return data[i].UserName + ' - ' + data[i].RoleName;
});
$('#taskresult3').append(html.join(',');
}
Also, keep in mind the semantic use of the <b> tag:
However, you should not use <b> for styling text; instead, you should use the CSS font-weight property to create boldface text.
https://developer.mozilla.org/en-US/docs/Web/HTML/Element/b
I'd suggest placing the HTML you append within a container that has font-weight: bold applied to it through CSS.

Sorting different ajax calls before writing them on page

I'm looping through an array an show the data on my screen. This part is working perfectly.
Now I want to sorting the elements on 'Startdate'.
for (var i = 0; i < schedule_id.length; i++) {
//Ajax call maken
$.ajax({
url: "http://api.viewer.zmags.com/schedules/" + schedule_id[i] + "?key=" + api_key
})
//WdInit after 10 calls
.done(function(data){
//Check publicatieID is not null
if (undefined === data.scheduleEntries[default_pub]|| null === data.scheduleEntries[default_pub]) {
}
else
{
//loopen doorheen resultaat call
$.each(data.scheduleEntries, function(index, entry){
//Datums
var sdate = moment(entry.startDate).format('DD/MM');
var edate = moment(entry.endDate).format('DD/MM');
var sdatecheckformat = moment(entry.startDate).format('YYYY/MM/DD');
var edatecheckformat = moment(entry.endDate).format('YYYY/MM/DD');
var sdatecheck = new Date(sdatecheckformat);
var edatecheck = new Date(edatecheckformat);
var today = new Date();
var timeDiff = Math.abs(sdatecheck.getTime() - today.getTime());
var diffDays = Math.ceil(timeDiff / (1000 * 3600 * 24));
//Check geldig
if(today<=edatecheck && diffDays<=14){
// Decide list order, load the thumbnail for each publication.
var place = "first";
$('#archive').prepend('<div class="container" id="'+entry.publicationID+'"></div>');
$('.container:' + place).append('<div class="thumb"></div>');
$('.thumb:' + place).css("background-image", 'url(' + entry.thumbnailURL + ')');
$('.thumb:' + place).css("filter", 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + entry.thumbnailURL + ',sizingMethod="scale")');
$('.thumb:' + place).css("-ms-filter", 'progid:DXImageTransform.Microsoft.AlphaImageLoader(src=' + entry.thumbnailURL + ',sizingMethod="scale")');
// Load the publication title below each thumbnail.
$('.thumb:' + place).after('<div class="title"></div>');
$('.title:' + place).append(entry.publicationName);
// Load the publication startsdate & enddate.
$('.title:' + place).after('<div class="date"></div>');
$('.date:' + place).append(sdate + " tot " + edate);
// Set up publication links.
$('.container:' + place).click(function(){
loadPub(entry.publicationID, entry.publicationName);
setActive(entry.publicationID);
//Change css of current element
});
}
//Eerste element tonen
if(0===first_element){
first_element++;
loadPub(entry.publicationID, entry.publicationName);
initFirst(entry.publicationID);
}
});
}
});
//Einde loop
}
Within this loop it is not possible to sort because we are writing the element immediately. Can you please help me a way to sort the data. Maybe getting all data first and sorting them by creating an array with the same schedules ID's but in a correct sorted way.
My code so far:
//Sortering
var arr = [];
var arr1 = [];
//Loopen 10 keer
for (var i = 0; i < schedule_id.length; i++) {
arr1.push("test");
//Ajax call maken
$.ajax({
url: "http://api.viewer.zmags.com/schedules/" + schedule_id[i] + "?key=" + api_key,
success: function(data) {
arr.push(data);
}
})
}
//Know looping throught array or something and sorting
You can use $.when() to wait for multiple deferreds to resolve.
For example:
var arrayOfAjaxPromises = [$.ajax("/page1"), $.ajax("/page2"), $.ajax("/page3")];
$.when.apply($, arrayOfAjaxPromises).done(function() {
// this callback gets called when all the promises are resolved
// responses are passed in the array-like arguments object, so they can be read sequentially
// or you can sort or process the way you want
var i;
for (i = 0; i < arguments.length; i+= 1) {
alert(arguments[i]);
}
});

jQuery autocomplete and locally fetched json data

I am struggling with jQuery UI Autocomplete and reading the autocomplete values from a variable that stores all the data returned from a json array. This is what the JavaScript looks like:
function populate_branch(){
$.get('/branch/list', {bank_name : $("#select_bank_name").val()}, function(branch_data){
branch_index = branch_data;
},"json");
};
for( var i = 0; i < branch_index.length; i++ )
branch_autocomplete += "" + "\'" + branch_index[i].branch_code + "\'" + "},";
$("#branch_auto_complete").autocomplete({
source: branch_autocomplete
});
What happens when I try use the auto complete textbox my console does something very weird, it returns this:
//localhost:3000/undefined%7B'label':'301105'%7D,%7B'label':'301205'%7…'label':'639625'%7D,%7B'label':'639845'%7D,%7B'label':'639948'%7D,?term=41
404 (Not Found)
Any help?
This is what I did to make this work,
var branch_index;
var branch_autocomplete, branch_name;
var index_branch_code = new Array();
function populate_branch(){
$.get('/branch/list', {bank_name : $("#select_bank_name").val()}, function(branch_data){
branch_index = branch_data;
for( var i = 0; i < branch_index.length; i ++ )
{
index_branch_code[i] = branch_index[i].branch_name + " (" + branch_index[i].branch_code + ")";
}
},"json");
};
$("#branch_auto_complete").autocomplete({
minLength: 0,
source: branch_code,
});
I just needed to push all the data into an array and create a new variable that is equal to index_branch_code so that the browser sees the variable as a flat file instead of it being dynamic.
You could try and this way.
$.ajax({
url: '/branch/list',
type: "GET",
data: {bank_name : $("#select_bank_name").val()} ,
dataType: "json",
async: false,
success: function(dataType) {
for( var i = 0; i < branch_index.length; i ++ ){
index_branch_code[i] = branch_index[i].branch_name + " ("+ branch_index[i].branch_code + ")";
}
$("#branch_auto_complete").autocomplete({
minLength: 0,
source: branch_code,
});
}
});

Help passing variables between functions in ajax callbacks

OK I am building something that makes an ajax request to one server where it determines the url it needs to then make a new ajax request to another place. Everything is progressing thanks to all the help at SO =) .. however I am stuck again. I am struggling with getting the variables to return to the different functions as I need. The second (jsonp) request returns a json function which looks like :
jsonResponse(
{"it.exists":"1"},"");
and my code...
var img = "null";
var z = "null";
$(document).ready(function()
{
$.ajax({
type: "GET",
url: "connect.php",
dataType: "xml",
success: function parseXml(data)
{
$(data).find("ITEM").each(function()
{
query = $("SKU", this).text();
query = 'http://domain.com/' + query + '?req=exists,json';
img = $("SKU", this).text();
img = '<img src="http://domain.com/' + img + '">';
var date =$("LAST_SCAN" , this).text();
$.ajax({
url: query,
dataType: 'jsonp'
});
$("table").append('<tr>'+'<td>' + (date) + '</td>' + '<td>' + (z) + '</td>');
});
}
});
});
// function required to interpret jsonp
function jsonResponse(response){
var x = response["it.exists"];
// console.log(x);
if (x == 0) {
console.log("NO");
var z = "NO IMG";
}
if (x == 1) {
console.log(img);
//this only returns the first image path from the loop of the parseXml function over and over
var z = (img);
}
return z;
}
So I guess my problem is a two parter.. one how do I get the img variable to loop into that if statement and then once that works how can I return that z variable to be used in the first xml parser?
Try this synchronous approach:
var itemQueue = [];
$(document).ready(function ()
{
$.ajax({
type: "GET",
url: "connect.php",
dataType: "xml",
success: function parseXml(data)
{
itemQueue= $(data).find("ITEM").map(function ()
{
return {
sku: $("SKU", this).text(),
date: $("LAST_SCAN", this).text()
};
}).get();
getNextItem();
}
});
});
function getNextItem()
{
var item = itemQueue[0];
var query = "http://domain.com/" + item.sku + "?req=exists,json";
$.ajax({
url: query,
dataType: 'jsonp'
});
}
function jsonResponse(response)
{
var item = itemQueue.shift();
if (itemQueue.length)
{
getNextItem();
}
var x = response["it.exists"];
var z = x == "0" ? "NO IMG" : "<img src=\"http://domain.com/" + item.sku + "\">";
$("table").append("<tr><td>" + item.date + "</td><td>" + z + "</td>");
}
Store 'date' in a global variable, and move the logic to append HTML elements into the jsonResponse function. You cannot return control flow from jsonResponse because it's called asynchronously, but you can continue doing anything you'd like from that function.

Merging JSON api Response using Javascript

I am trying get paged json responses from Topsy (http://code.google.com/p/otterapi/) and am having problems merging the objects. I want to do this in browser as the api rate limit is per ip/user and to low to do things server side.
Here is my code. Is there a better way? Of course there is because this doesn't work. I guess I want to get this working, but also to understand if there is a safer, and/or more efficient way.
The error message I get is ...
TypeError: Result of expression 'window.holdtweetslist.prototype' [undefined] is not an object.
Thanks in advance.
Cheers
Stephen
$("#gettweets").live('click', function(event){
event.preventDefault();
getTweets('stephenbaugh');
});
function getTweets(name) {
var MAX_TWEETS = 500;
var TWEETSPERPAGE = 50;
var BASE = 'http://otter.topsy.com/search.json?type=tweet&perpage=' + TWEETSPERPAGE + '&window=a&nohidden=0&q=#' + name + '&page=1';
var currentpage = 1;
alert(BASE);
$.ajax({
dataType: "json",
url: BASE,
success: function(data) {
window.responcesreceived = 1;
var response=data.response;
alert(response.total);
window.totalweets = response.total;
window.pagestoget = Math.ceil(window.totalweets/window.TWEETSPERPAGE);
window.holdtweetslist = response.list;
window.holdtweetslist.prototype.Merge = (function (ob) {var o = this;var i = 0;for (var z in ob) {if (ob.hasOwnProperty(z)) {o[z] = ob[z];}}return o;});
// alert(data);
;; gotTweets(data);
var loopcounter = 1;
do
{
currentpage = currentpage + 1;
pausecomp(1500);
var BASE = 'http://otter.topsy.com/search.json?type=tweet&perpage=' + TWEETSPERPAGE + '&window=a&nohidden=0&q=#' + name + '&page=' + currentpage;
alert(BASE);
$.ajax({dataType: "json", url: BASE, success: gotTweets(data)});
}
while (currentpage<pagestoget);
}
});
};
function gotTweets(data)
{
window.responcesreceived = window.responcesreceived + 1;
var response = data.response;
alert(response.total);
window.holdtweetslist.Merge(response.list);
window.tweetsfound = window.tweetsfound + response.total;
if (window.responcesreceived == window.pagestoget) {
// sendforprocessingsendtweetlist();
alert(window.tweetsfound);
}
}
You are calling Merge as an static method, but declared it as an "instance" method (for the prototype reserved word).
Remove prototype from Merge declaration, so you'll have:
window.holdtweetslist.Merge = (function(ob)...
This will fix the javascript error.
This is Vipul from Topsy. Would you share the literal JSON you are receiving? I want to ensure you are not receiving a broken response.
THanks to Edgar and Vipul for there help. Unfortunately they were able to answer my questions. I have managed to work out that the issue was a combination of jquery not parsing the json properly and needing to use jsonp with topsy.
Here is a little test I created that works.
Create a doc with this object on it ....
RUN TEST
You will need JQUERY
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.min.js"></script>
And put the following in a script too. The is cycle through the required number of tweets from Topsy.
Thanks again everyone.
$("#gettweets").live('click', function(event){
event.preventDefault();
getTweets('stephenbaugh');
});
var MAX_TWEETS = 500;
var TWEETSPERPAGE = 50;
var BASE = 'http://otter.topsy.com/search.json';
var currentpage;
var responcesreceived;
var totalweets;
var pagestoget;
var totalweets;
var TWEETSPERPAGE;
var holdtweetslist = [];
var requestssent;
var responcesreceived;
var tweetsfound;
var nametoget;
function getTweets(name) {
nametoget=name;
currentpage = 1;
responcesreceived = 0;
pagestoget = 0;
var BASE = 'http://otter.topsy.com/search.js?type=tweet&perpage=' + TWEETSPERPAGE + '&window=a&nohidden=0&q=#' + nametoget + '&page=1';
$('#gettweets').html(BASE);
$.ajax({url: BASE,
dataType: 'jsonp',
success : function(data) {
getalltweets(data);
}
});
};
function getalltweets(data) {
totalweets = data.response.total;
$('#gettweets').append('<p>'+"total tweets " + totalweets+'</p>');
$('#gettweets').append('<p>'+"max tweets " + MAX_TWEETS+'</p>');
if (MAX_TWEETS < totalweets) {
totalweets = 500
}
$('#gettweets').append('<p>'+"new total tweets " + totalweets+'</p>');
gotTweets(data);
pagestoget = Math.ceil(totalweets/TWEETSPERPAGE);
var getpagesint = self.setInterval(function() {
currentpage = ++currentpage;
var BASE = 'http://otter.topsy.com/search.js?type=tweet&perpage=' + TWEETSPERPAGE + '&window=a&nohidden=0&q=#' + nametoget + '&page=' + currentpage;
$.ajax({url: BASE,
dataType: 'jsonp',
success : function(data) {
gotTweets(data);
}
});
if (currentpage == pagestoget) {
$('#gettweets').append('<p>'+"finished sending " + currentpage+ ' of ' + pagestoget + '</p>');
clearInterval(getpagesint);
};
}, 2000);
};
function gotTweets(data)
{
responcesreceived = responcesreceived + 1;
holdlist = data.response.list;
for (x in holdlist)
{
holdtweetslist.push(holdlist[x]);
}
// var family = parents.concat(children);
$('#gettweets').append('<p>receipt # ' + responcesreceived+' - is page : ' +data.response.page+ ' array length = ' + holdtweetslist.length +'</p>');
// holdtweetslist.Merge(response.list);
tweetsfound = tweetsfound + data.response.total;
if (responcesreceived == pagestoget) {
// sendforprocessingsendtweetlist();
$('#gettweets').append('<p>'+"finished receiving " + responcesreceived + ' of ' + pagestoget + '</p>');
}
}

Categories

Resources