JavaScript auto-incrementing a variable in jQuery and AJAX - javascript

I have JavaScript using jQuery and AJAX which creates a dynamic array, which has some values used for AJAX request as below;
<script type="text/javascript">
var array = Array("y","y","x","y","y","y");
function updateBackground(cellId, titleId) {
var i = 0;
$.ajax({
type: "POST",
url: "ajax.php",
data: {
filename: Array(array[i], "testdata", $("#"+titleId).html())
},
success: function(response){
$("#"+cellId).css("background-image", "url('pdfthumb/" + response + "')");
}
});
i++;
}
</script>
The script is suppose to submit values in the array in array[i] for each AJAX request. I made a variable var i which auto increments.. But the script is not working.. The script works well if array[i] is replaced by array[0] or array[1] etc..
How can I solve the syntax error?

Every time you call updateBackground() i = 0 (again). May be you must initialize i outside of the function.
What happens if i > array.length? And I would rename the variable.

You don't have an iterator. Your variable i gets set to 0 every time the function runs. The increment at the end is useless.
Maybe you need something like this?
var array = Array("y","y","x","y","y","y");
function updateBackground(cellId, titleId) {
for( var i = 0; i < array.length; i++ ) {
$.ajax({
type: "POST",
url: "ajax.php",
data: {
filename: Array(array[i], "<?php echo $dir; ?>", $("#"+titleId).html())
},
success: function(response){
$("#"+cellId).css("background-image", "url('pdfthumb/" + response + "')");
}
});
}
}

Each time you call updateBackground() function, the i variable is being reinitialized. It's just a local variable and as soon as the function finishes it's being destroyed by GC. You could do something like this:
var UpdateBackground = {
array: [..],
counter: 0,
doUpdate: function(cellId, titleId) {
// AJAX request
this.counter++;
}
};
UpdateBackground.doUpdate(1, 1);
UpdateBackground.doUpdate(1, 1);

I think that you should send the whole array maybe as a commaseparated string and instead and make just one ajax request, because http-requests are expensive and change the server side code accordingly. And fetch the cellids as an array.
If you think that you have a long list or a table it can be like a lot of requests. Do the stuff in client code and do the stuff in server code and keep the number of http-requests as few as possible.
And use the join method on the array.
var arr = [ 'y', 'y' ];
arr.join(',');
// outputs y, y

I fixed it... Thank you so much #Jed, #Pointy, #Crozin, and #Lord Vader for helping me to figure it out.... :)
I just take var i = 0; outside the loop.... above var array like;
var i = 0;
var array = Array("y","y","x","y","y","x");

Related

Javascript/jQuery set variable to object property for multiple $.ajax calls

I am looking to send a number of different queries via $.ajax as JSON.
I have stored these queries in an object using the following:
var objectName = {
"name1": {
"queryName": "longname1",
"queryAction": "JSONtoSend"
},
"name2": {
"queryName": "longname2",
"queryAction": "JSONtoSend"
},
};
I am then going through the queryActions and setting them:
for (var i = 0, len = Object.keys(objectName).length; i < len; ++i) {
var indexName = Object.keys(objectName)[i];
objectName[indexName].queryAction = "";
var JSONtoTransfer = objectName[indexName].queryAction;
}
$.ajax({
type: "POST",
url: 'URL',
data: JSONtoTransfer,
contentType: "application/json; charset=utf-8",
dataType: "json",
success: function(dataReturn){
alert(dataReturn.blah);
}
});
I am unable to set the var JSONtoTransfer. It gives me an unexpected [ error. How do I get around this? I get the same error if I enter it straight into the data parameter of $.ajax.
The code I am using is storing the queries in the object correctly, but I need a way to iterate through them all and send via $.ajax.
Thank you for the help. This code is probably not the most efficient way of doing things, so if anyone has any advice, it's more than welcome too :-)
So I wrote the original code wrong, the $.ajax call should be included in the for statement. So it actually iterates....
Anyway, what I found to work was creating an array, pushing the queryAction into it and then stringifying it...
Few problems:
JSONtoTransfer is out of scope of your ajax call. If you want to populate JSONtoTransfer on every iteration and make an ajax request with this different value each time - put the ajax call inside the for loop (although I would seriously consider refactoring this so that you make one ajax call, and deserialize it differently (if it's your server-side code handling it))
You're setting objectName[indexName].queryAction to an empty string, then assigning this value to JSONtoTransfer (now always going to be an empty string)
You have your for syntax a bit muddled up. Best practice would be to change
for (var i = 0, len = Object.keys(objectName).length; i < len; ++i) {
to
for (var i = 0; i < Object.keys(objectName).length; ++i) {
i.e. there's no need to keep initialising len to the same value. NOTE: This is more for readability, not (so much) performance. If you had another use for len inside the loop this advice wouldn't apply.
Your variable objectName is in fact JSON data already. I might be wrong but I think this should work (with less code):
var jsonData = {
"name1": {
"queryName": "longname1",
"queryAction": "JSONtoSend"
},
"name2": {
"queryName": "longname2",
"queryAction": "JSONtoSend"
},
};
//Post with AJAX
$.post('url.php', jsonData, 'json')
.done(function(data) {
alert('Succes!')
})
.fail(function(data) {
alert('Failed!')
});
//This does the same (Post with AJAX)
$.ajax({
url: 'url.php', //Get action attribute of the form
type: "POST",
data: jsonData,
dataType: "json",
.done(function() { //or success: function() {
alert( "success" );
})
.fail(function() { //or error: function() {
alert( "error" );
})
.always(function() { //or beforeSend: function() {
alert( "complete" );
});
});
I am not sure what you want but as pointed out by others there are many issues with your code, but i think you want to execute ajax call one after the other iteratively. if that is what you want then take a look at jQuery deffered -docs are here.Hope that helps

Creating divs in AJAX loop

I am getting data from the server side using AJAX, I am now trying to populate data from from a list of objects into divs, the problem I am having is that I can not create the div while inside of the foreach loop.
$(document).ready(function () {
var divs = "";
var url = "../Graphs/CreateChart";
$.ajax({
type: 'POST',
url: url,
success: function (data) {
for (var i in data) {
var x = data[i];
for (var j in x) {
var val;
if (x.hasOwnProperty(j)) {
val = x[j].SpName;
if (x[j].SpName != "undefined") {
$('#a').appendTo('#content');
createBarChart("#a", "USP_Charts_BarChart1");
}
}
}
}
}, dataType: "json",
cache: false
});
});
</script>
I am trying to populate where it says "#a" with val and also then I need to populate the div I write with the val for the id, but when I try to put the document.write inside of the loop, I get a blank screen, any ideas why it would do this?
you're trying to append a created variable to your content? Try making the markup a string FIRST then appending it.
To test it try it without data.
$("<h2>HI</h2>").appendTo("#content");
If that works, then make a string that is the markup you want, with the data you need.
$("<a data='"+data.variable+"'></a>").appendTo("#content");
append and appendTo are VERY similar, but you need to use a string, not just an identifier, if the object doesn't exist yet.

Setting Localstorage Variable Name to a Variable's value

I am using a javascript loop to create localstorage variables. For some reason, all the localstorage values are null except for the last one. Does anyone know why?
Here is my code:
function setValues() {
var json = jQuery.parseJSON(data);
for (var i=0; i<json.length; i++)
{
var id = json[i].id;
$.ajax({
url: url,
crossDomain: true,
type: 'post',
data: {
'theid': id
},
success: function (data2) {
window.localStorage['club'+id] = data2;
},
});
}
}
function getValue(id) {
console.log(window.localStorage.getItem('club'+id));
}
I call getValue() else where in the code, it is irrelevant to the issue. If the 'id' is the last id that was used for adding to the localstorage, it isn't null. However, it seems as if all the previous values are overwritten.
How can I fix this issue? Any help would be appreciated. Thanks!
ANSWER REWRITE BASED UPON THE OP's QUESTION CHANGE
This is actually a very common JavaScript issue and almost impossible to search for unless you already know the answer the magic words involved.
Because your wording is slightly different than the usual issue, I'm not going to vote to close this question but rather, explain what is going on.
There is only one copy of the variable i and that variable is changed as the loop runs. By the time the callbacks return, that loop is long over and i has reached its final value.
What you need to do is capture a local copy of that value. There are two ways to do it -- I'll show the easiest one to read:
function doAjax(i) {
// this 'i' is private.
var id = json[i].id;
$.ajax({
url: url,
crossDomain: true,
type: 'post',
data: {
'theid': id
},
success: function (data2) {
window.localStorage['club' + id] = data2;
}
});
}
function setValues() {
var json = jQuery.parseJSON(data);
for (var i = 0; i < json.length; i++) {
doAjax(i);
}
}
The other way to do this is to use a closure and an anonymous function:
function setValues() {
var json = jQuery.parseJSON(data);
for (var i = 0; i < json.length; i++) {
(function (i2) {
// this 'i' is private.
// Givign it the name of 'i2' just to be clear
var id = json[i2].id;
$.ajax({
url: url,
crossDomain: true,
type: 'post',
data: {
'theid': id
},
success: function (data2) {
window.localStorage['club' + id] = data2;
},
});
// this is the 'i' from the main loop
}(i));
}
}
For more info see
How do JavaScript closures work?

Ajax Call in For Loop, For Loop Completing Before all Calls are Made

I have created a for loop that loops the number of times that an element appears in a container. The for loop grabs some data from the HTML and creates a JSON url which will then return a value. That value should then be added to the HTML in the appropriate place.
The problem seems that the for loop completes before all of the Ajax calls are made, so only the last value is being added to the HTML. I thought that I could make sure that the readystate is equal to 4, but that solution did not work. I also tried using complete, rather than success as an Ajax Event. Any insights? Here is my the code.
for(var index = 0; index < $('#wizSteps #step6 label').length; index++){
var priceCount;
console.log(index);
var currentSelect = $('#wizSteps #step6 label[data-pricepos="'+index+'"]');
url = 'http://www.thesite.com/api/search.json?taxonomy=cat3435' + currentSelect.find('input').attr('name');
jQuery.ajax({
url: url,
dataType: "JSON",
success: function( data ){
var totalResult = data.totalNumberOfResults;
console.log(currentSelect);
currentSelect.find('.itemCount').text(totalResult);
}
});
}
It looks like you don't necessarily need the requests to finish in order, you just need to keep track of currentSelect in a way that works. For that, you can use the context ajax option:
for (var index = 0; index < $('#wizSteps #step6 label').length; index++) {
var currentSelect = $('#wizSteps #step6 label[data-pricepos="' + index + '"]');
url = 'http://www.thesite.com/api/search.json?taxonomy=cat3435' + currentSelect.find('input').attr('name');
jQuery.ajax({
url: url,
dataType: "JSON",
context: currentSelect,
success: function (data) {
var totalResult = data.totalNumberOfResults;
this.find('.itemCount').text(totalResult);
}
});
}
That is ok, the calls are not supposed to be done this way. They are only initiated in the loop.
Ajax is asynchronous. The queries are completed later, may be in different order.
If you want to be sure that every call is completed before you do the next one,
you must integrate the next call into the callback function of the previous.
In your case the variable may be overwritten in the call back function.
You can learn more on this here:
Asynchronous Javascript Variable Overwrite
Another interesting question/discussion related to the topic:
What are the differences between Deferred, Promise and Future in JavaScript?
It does not directly answer your question, but helps to understand the problem deeper.
The point is that you probable don't need the loop at all (or you do but in a completely different form).
You should try creating a recursive function, that you will call again in the success of the ajax call, this way you will be sure that the next ajax call will be called only once the previous call is done.
If you want the requests in a sequence, you can work with a queue.
First build the queue:
var queue = [],
index,
stepLength = $('#wizSteps #step6 label').length;
for(index = 0; index < length; index++){
var priceCount;
console.log(index);
var currentSelect = $('#wizSteps #step6 label[data-pricepos="'+index+'"]');
url = 'http://www.thesite.com/api/search.json?taxonomy=cat3435' + currentSelect.find('input').attr('name');
queue.push([url, currentSelect]);
}
And after that do the serial ajax requests:
function serialAjax() {
if(queue.length === 0) {
return;
}
var queueData = queue.shift(),
url = queueData[0],
currentSelect = queueData[1];
jQuery.ajax({
url: url,
dataType: "JSON",
success: function( data ){
var totalResult = data.totalNumberOfResults;
console.log(currentSelect);
currentSelect.find('.itemCount').text(totalResult);
serialAjax();
}
});
};
// call the function
serialAjax();

Global variables in Javascript not updating

I have spent the last 30 mins figuring this out.
Let's assume the following case:
<script>
var x = 0 ; //global variable
function compute() {
x = x+1;
}
</script>
Should the value of x be incremented so I can access it into a function later on?
I have the following codes:
var id1 = 0;
var id2 = 0;
$.ajax({
url: "http://localhost/twee/chat/comment",
type: 'POST',
data: form_data,
success: function(data) {
var data1 = parseInt(data);
id1 = id2 = data1;
}
});
I want to be able to access the values of id1 and id2 (updated since i declared them as 0) in a later function.
However, the value is staying zero and data1 is retrieved just fine.
I dont know when you try to use the ID's, but the ajax call is asynchronus, so if you try to read the variables like this:
var id1 = 0;
var id3 = 0 ;
$.ajax({
url: "http://localhost/twee/chat/comment",
type: 'POST',
data: form_data,
success: function(data) {
var data1 = parseInt(data, 10);
id1 = id2 = data1;
alert(id1) // Will alert whatever number returned as data.
}});
alert(id1) // Will alert 0
The second alert will be called almost simultaneously with the ajax call, and at that point the data has not been updated yet, while the first alert will not be called until the data has returned. If you are going to use the ID's, you will have to use them within your success-callback, or in a function that is called within your success-callback.
Are you sure that you're checking the value of id1 after the success callback runs? ajax is an asynchronous operation, your callback won't be called until the response comes back from the server.
Your ajax callback is asynchronous. It won't run the success function until after the remote server responds. Once it does, your function is executed, and the variable is incremented.
This is a difficulty in Javascript programming, and asynchronous programming in general: there are a number of balls in the air at once, and it is difficult to reason about how they might complete their operations, and when you can see the results.
It's very easy to think of the $.ajax() call as "get the results from the server," but it's really, "make a request to the server." Who knows when it might finish?

Categories

Resources