I am trying to do something really simple - initialize an array in Javascript. And it's not working in Google Chrome. Here is the code:
status = [];
for(i=0; i < 8; i++)
status[i]=false;
alert(status.length); //It says 0 when it should say 8
What gives?
The assignment of your status variable, clashes with the window.status property.
Chrome simply refuses to make the assignment.
The window.status property, sets or gets the text in the status bar at the bottom of the browser.
I would recommend you to either, rename your variable or use an anonymous function to create a new scope, also remember to always use var for declaring variables:
(function () {
var status = [];
for (var i = 0; i < 8; i++)
status[i] = false;
alert(status.length);
})();
Change the variable name. Seems like status is a property of window, and Chrome makes it inmutable
.
I didn't expect that, too.
The problem here is what status is attached to. You are using it off the global/window scope.
Back in the good ole days we were able to set the text in the status bar. How you would do it is by setting window.status to a string value. So what you are doing is NOT setting a variable, but changing the string of the browser's status bar.
Related
I have a single javascript where I have declared all my variables in the
$(document).ready(function(){
//variables
});
The values of these variables are initialized as well and mostly they are HTML elements. The elements are determined using the ids via document.GetElementById(). Some of these elements exists only in a different page which is not loaded in the browser yet. This results in null error when the variables holding the elements are used for a different purpose.
var container_element = document.getElementById('unique-id');
var count = container_element.getElementsByTagName("div").length;
Since the element with "unique-id" is present in another page which is not loaded in the browser, the second line would return an error because container_element is null. To fix this, I changed the code to
var container_element = document.getElementById('unique-id');
if(container_element) {
var count = container_element.getElementsByTagName("div").length;
}
Is this is the only way to handle such a thing? Should I have to do a null check for every function that I invoke via a variable or is there any other solution or standard / best practice?
You need a guard like that any time the element may or may not exist as of when you use getElementById. You can use the if you've shown, or
var container_element = document.getElementById('unique-id');
var count = !container_element ? 0 : container_element.getElementsByTagName("div").length;
or similar.
Another option is to react to the exception:
var container_element = document.getElementById('unique-id');
var count;
try {
count = container_element.getElementsByTagName("div").length;
} catch (e) {
count = 0;
}
I notice you're using jQuery but not using it in that code. Which is too bad, because if you were, jQuery's set-based nature would mean you didn't need the guard:
var container_element = $('#unique-id');
var count = container_element.find("div").length;
Even though container_element is an empty set, you can call methods on it. Most jQuery methods provide intelligent handling of empty sets. For instance, using find on an empty set returns a (new) empty set, as above.
You still have the option to know whether the element exists (more in this question's answers):
if (container_element[0])
// or
if (container_element.length)
I am trying to do something really simple - initialize an array in Javascript. And it's not working in Google Chrome. Here is the code:
status = [];
for(i=0; i < 8; i++)
status[i]=false;
alert(status.length); //It says 0 when it should say 8
What gives?
The assignment of your status variable, clashes with the window.status property.
Chrome simply refuses to make the assignment.
The window.status property, sets or gets the text in the status bar at the bottom of the browser.
I would recommend you to either, rename your variable or use an anonymous function to create a new scope, also remember to always use var for declaring variables:
(function () {
var status = [];
for (var i = 0; i < 8; i++)
status[i] = false;
alert(status.length);
})();
Change the variable name. Seems like status is a property of window, and Chrome makes it inmutable
.
I didn't expect that, too.
The problem here is what status is attached to. You are using it off the global/window scope.
Back in the good ole days we were able to set the text in the status bar. How you would do it is by setting window.status to a string value. So what you are doing is NOT setting a variable, but changing the string of the browser's status bar.
How to loop through this data: (I have no control over format)
{"rowCount":3,"1":{"K":"2009","V":"Some Data"},"2":{"K":"2010","V":"More Data"}}
Above is a console.log(results) and results is a string
var r = JSON.parse(results);
var t;
for(var i=1;i<=r.rowCount;i++) {
t=r[i].V;
tableData.push(
{title:t, year:'2009', hasChild:true, color: '#000'}
);
}
Error: TypeError: 'undefined' is not an object (evaluating 'r[i].V')
I cannot get it to evaluate the variable i. What am I doing wrong?
Thanks
UPDATE
The incoming data had a bad rowcount causing the error. The accepted answer however is correct... just user error on my part not catching the bad incoming data. Had I put a console.log inside the loop I would have realized the error was actually happening after two successful loops. oops
I assume r.rowCount should be j.rowCount.
Ideally you should also initialise the i variable if you haven't already (i.e. with the var keyword).
(I've also moved the var t declaration outside the loop, to make it clear that it's the same t throughout and you're just changing its value. You shouldn't redeclare it with var each time – although I doubt this affects the output.)
var j = {"rowCount":2,"1":{"K":"name","V":"john"},"2":{"K":"name","V":"sue"}};
var t;
for (var i = 1; i <= j.rowCount; i++) {
t = j[i].V;
console.log(t);
}
Working demo – JSFiddle
How do I increment an integer inside a variable, every time that variable is called? Javascript.
var a=0;
var t=loadXMLDoc("http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist="+x[a].getElementsByTagName("name")[0].childNodes[0].nodeValue+"&api_key=83e386b0ba08735e3dee9b118478e56d&lang=en").getElementsByTagName("bio");
for (i=0;i<20;i++)
{
document.write("<div><button type='button' onclick='document.getElementById("+i+").innerHTML=t[0].getElementsByTagName(\"summary\")[0].childNodes[1].nodeValue;'>Open Bio</button></div>");
}
I'm not sure how I would go about incrementing variable a. I need it to increase by 1 every time variable t is called in the for loop.
When I put all of the code in the for loop I get [object node list] returned so this method is not desired.
If I understood your question correctly, you could define your own getters and setters for the property.
var o = {}
o.__defineSetter__('property', function(value) { this._counter = 0; this._holder = value; })
o.__defineGetter__('property', function() { console.log(this._counter++); return this._holder; })
The counter would be reset every time o.property is assigned a value
o.property = 'Some value'
and then increase every time the property is accessed.
So,
console.log(o.property)
would print
0
Some value
to the console. And if you do it again, it would print
1
Some value
After your edit I think I can see your problem now. You will need to put the loadXMLDoc statement in the loop (since you want to load 20 different XML files), but you can't assign the result of every call to the same variable t - as once the button is clicked, the handler will evaluate t and get only the last value.
Instead, use an array:
var bios = []; // empty array
for (var i=0; i<20; i++) {
var artist = x[i].getElementsByTagName("name")[0].childNodes[0].nodeValue,
doc = loadXMLDoc("http://ws.audioscrobbler.com/2.0/?method=artist.getinfo&artist="+artist+"&api_key=83e386b0ba08735e3dee9b118478e56d&lang=en"),
bio = doc.getElementsByTagName("bio")[0].getElementsByTagName("summary")[0].childNodes[1].nodeValue;
bios[i] = bio; // store it in the array
document.write("<div><button type='button' onclick='document.getElementById("+i+").innerHTML=bios["+i+"];'>Open Bio</button></div>");
}
Of course, while that will work it's a bunch of bad practises, including
unsecured accessing of DOM nodes/properties. If the xml changes its format, you will get lots of exceptions here. You might be sure now that this never happens, but wrapping artist and bio in try-catch might not be a bad idea.
snychronous Ajax. One can do better than that.
loading 20 documents (and that sequentially!) even if you don't need them. It might be worth to try loading each of them only when the respective button is clicked.
document.write
Inline attribute event handlers
…and creating them even by JS.
I have run in to a stupid problem...
I declared a new variable called leadingZero. I save the modified .js file and run the project with a breakpoint on the leadingZero assignment and in watcher window it says its undefined after passing this line, but all the other declarations here are working fine and I can see the assigned values. needless to say the getObject call does not work now.
var leadingZero = 0; //new variable
var chkActive;
var chkSubscribe;
var hdnItem = getObject('hdnItemCounter');
var ItemCount = parseInt(hdnItem.value) + 1;
for (intCounter = 2; intCounter <= ItemCount; intCounter++) {
chkActive = getObject('dgrProductList_ctl0' + leadingZero + intCounter + '_chkActive');
}
Check this http://jsfiddle.net/DHDsE/
Not getting the undefined problem tho, but having to add toString() to leadingZero for it to render in the console.log, so maybe that's your issue too.
You did set the breakpoint on the line below, didn't you?
Because if you set it on the line var leadingZero = 0; it halts before the line is evaluated, which explains the undefined value in the watcher.
Also, as gillesc pointed out, your leadingZero must be a string, otherwise you're adding up intCounter and leadingZero, rather than concatenating them.
The problem seemed to be changes to the js were not loaded in ie cache. even after closing ie, rebuilding the project and running again, I still need to hit ctrl+f5 on the page to load the new javascript