className null or not an object again - javascript

The problem with IE.
Here is the code:
if (($.browser.msie)) {
var first_el = 0;
var targie = document.getElementById(targId).getElementsByTagName("div");
for (var i = 0; i < targie.length, first_el < 1; i++) {
if ((typeof targie[i].className != 'undefined') && (targie[i].className != null)) {
if ((targie[i].className == "category list even") || (targie[i].className == "category list") || (targie[i].className == "good list even") || (targie[i].className == "good list")) {
var targ = targie[i];
first_el += 1;
}
}
}
}
And the error - className null or not an object
Found a similar topics, but the solutions did not help me.
Thanks in advance

I don't think that's the actual error message. It is more like cannot access property "classname", targie[i] is null or not an object, isn't it?
Your problem seems to be the condition part of your loop: i < targie.length, first_el < 1 which uses the comma operator. This means your loop will run as long as it did not find an element - even if there are no more elements. Change it to i < targie.length && first_el < 1 and it should work.
Btw, you seem to use jQuery. Why don't you use a DOM selector like $("#"+targid+" div.list")? Then, you could use an each loop to set up your variables, or just add a :first selector and go on with jQuery.

I think you should use getAttribute('class'); if user's broser is IE

Related

How to fix code that returns undefined?

I have this code:
const liked_users = promises[1];
const disliked_users = promises[0];
if (liked_users.length > 0 || disliked_users.length > 0){
for(var i = 0; i < liked_users.length; i++){
for(var j = 0; j < disliked_users.length; j++){
for(var k = 0; k < _USERS.length; k++){
if(_USERS[k].useruid == liked_users[i].likedUseruid || disliked_users[j].dislikedUseruid){
_USERS.splice(i, 1);
i--;
break;
}
basically what is happening is that I access the firebase database and I pull out some data from my objects.
The problem comes where sometimes liked_users is going to be blank and therefore liked_users[i].likedUseruid will return undefined. When they are defined, the code runs fine.
How can I put in some conditional or block of code that allows it to be read in a way that accepts it can be undefined or doesn't run the code until it is defined? I can show more code if it will help.
In JavaScript if you put just variable name in if condition then it will check its available or not.
For example put this block
if(_USERS[k].useruid == liked_users[i].likedUseruid || disliked_users[j].dislikedUseruid){
....
}
in this
if(_USERS[k].useruid && liked_users[i].likedUseruid && disliked_users[j].dislikedUseruid){
....
}
The above condition will check that _USERS[k].useruid is available or not and will continue...
You can make condition as per your need.
I hope this will help you.

Having trouble with a for loop not iterating enough

So I have a problem with this FOR loop that I just can't quite figure out. In this case, I know this needs to iterate as least twice. The array, at a minimum, looks something like this...
dTrackerArray = {sParentValue, 1234, sParentValue, 5678}
But for some reason this for loop is only removing one instance instead of all of them.
var check = $.inArray(sParentValue, dTrackerArray);
if (check != -1) {
for(var i = dTrackerArray.length; i > 0; i--) {
if( dTrackerArray[i] === sParentValue ) {
dTrackerArray.splice(i,1);
dTrackerArray.splice(i-1,1);
}
}}
I really appreciate any help I can get here! Thanks!
EDIT: The 2nd splice is to remove the 1234 "associated" with the sParentValue. It seems to work ok.
The problem is in for loop. you start from: var i = dTrackerArray.length and take dTrackerArray[i] this element does not exist. More over you forgot to interate with 0 index element. So you have to change your for loop to:
for(var i = dTrackerArray.length-1; i >= 0; i--)
Easy to miss but you need i >= 0.
EDIT:
Although I think your main issue is that you're modifying an array while your looping. Obviously with my fix you'll get an out of bounds error on the second splice.
var check = $.inArray(sParentValue, dTrackerArray);
if (check != -1) {
for(var i = dTrackerArray.length; i >= 0; i--) {
if( dTrackerArray[i] === sParentValue ) {
dTrackerArray.splice(i,1);
dTrackerArray.splice(i-1,1); //when i == 0 then exception
}
}}
Since you know the format of the array you can do this with a while loop:
var check = $.inArray(sParentValue, dTrackerArray);
while(check > -1)
{
dTrackerArray.splice(check,1);
check = $.inArray(sParentValue, dTrackerArray);
}
You've already stepped through this with a debugger? That's probably all you'd need to do to understand what's happening here. I'd put this in a comment, but I don't have those privileges yet.

Remove item from Javascript array on change

I have a bit of situation. Basically I am adding an item to JavaScript array, which I am populating on select box change. But the problem is when I input 0, it should removed from an array.
Here is the code
var addon = new Array();
function updateAddons(){
addon.length=0;
var plan = new Array;
var planQty = new Array;
plan.length=0;
planQty.length=0;
for(var j =0 ; j< 3; j++){
$("select[name='addon_"+j+"[]'] option:selected").each(function(){
var item = {
product_name : $(this).attr('pn'),
product_cost : $(this).attr('cost'),
product_id : $(this).val()
};
if(item.product_id != 0){
plan.push(item);
}
});
$("input[name='addonQty_"+j+"[]'] ").each(function(){
if($(this).val() != 0){
planQty.push($(this).val());
}
});
}
for(var i =0; i < plan.length; i++){
var item = {
product:plan[i],
product_qty:planQty[i]
}
if(item.product.product_id != 0){
addon.push(item);
}
}
}
I have created a jsfiddle click here to view that. (check your browser console for the complete object.)
If someone can help. And please explain your answer.
Regards
I solved it myself. put a artibitary number in place of 0 and not adding in the final array.
Thanks
The main problem with you code is the following statement:
if($(this).val() != 0)
The problem is if the input is empty the value is undefined. In javascript undefined is not equal to 0. An easy way to solve this is to test for undefined as well:
if($(this).val() != 0 && $(this).val() != undefined)

Code review - if else function

I cannot for the life of me understand why I am getting the error:
"Type error: eCurVar is undefined". Please review the code below.
var aBBTemplates = document.getElementsByClassName ("cBBTemplates");
var i = 2;
while (i < aBBTemplates.length)
{
var eCurVar = aBBTemplates[i];
if (eCurVar === e.target)
{
eCurVar.style.zIndex = 3;
// type error: eCurVar is undefined on the following line.
} else if (eCurVar.style.zIndex === 3) {
console.log (eCurVar);
eCurVar.style.zIndex = 3-1;
} else
{
console.log (eCurVar)
eCurVar.style.zIndex = i;
}
i--;
}
After each iteration i is decremented of one unit... and after three iterations it becomes negative; so you read aBBTemplates[-1] you get undefined.
When you can't understand what's going on with few console.logs, your best bet is to add a debugger; instruction, and open your devtool (usually by pressing F12).
As for your problem you could fix it by adding a check on i:
while (i < aBBTemplates.length && i >= 0) {
}
In the second case aBBTemplates[i] probably returns null
You start with i equal to 2. Lets assume that aBBTemplates[2] returns something meaningful. You do someting with it and them decrement i. Lets assume aBBTemplates[1] in meaningful.
Keep going, and sooner or lates i becomes -1, which will definately not be meaningful when reading aBBTemplates[-1]
Into if function check if also eCurrVar is not a null
if (eCurVar != null && eCurVar === e.target){
// your code
} else {
// if ecurvar == null or ecurvar != e.targer
}
Also in while check if your i is possitive number, because array do not contains items with negative indexes:
while(i >= 0 && i < aBBTemplates.length)

Prevent javascript from going out of an array

Is there any way I can prevent javascript from dropping an error if I try to go into a non existing array index?
Example: array[-1] would return error and eventually break all my code. How can I let it just return 'undefined' and let my script go on? I can implement an if statement before checking the array (so that if the index is minor than zero or major than the array size it would skip it) but this would be very tedious!
this is my code:
if (grid[j-1][i])
n++;
if (grid[j+1][i])
n++;
if (grid[j][i+1])
n++;
if (grid[j][i-1])
n++;
if (grid[j-1][i-1])
n++;
if (grid[j+1][i+1])
n++;
if (grid[j-1][i+1])
n++;
if (grid[j+1][i-1])
n++;
It is inside of two loops which both sees J and I starting from zero. I don't want to change them and neither writing another if statement (as you can see, there are already too much of them!). Is there any solution?
Thanks!
If you know the measures of your grid, you can put "sentinel cells" around it.
If you add a -1st index to an array x, it does not count to x.length. Putting an additional last element into the list would increment x.length.
I daresay using sentinel cells combined with the arithmetic counting algorithms mentioned by d_inevitable would be the fastest solution, since it would not involve branches. You even can omit the !! because true will evaluate to 1 and false to 0 in an equalization.
Update:
Do not use index -1. Its an awful lot slower that normal array indexes. See http://jsperf.com/index-1.
You could use ||, which muffles errors, e.g.:
(grid[j-1] || [])[i] || false
(I haven't tested this, but it should work)
Edit: updated based on am not i am's suggestion
A less tedious way while still using ifs would be checking the first index if it's defined:
if (typeof grid[j-1] != "undefined" && grid[j-1][i])
You could create a function to do the checks:
function getArrayValue(arr,key) {
if( key < 0 || key >= arr.length) return null;
return arr[key];
}
But really you should be avoiding out-of-bounds keys anyway.
I would do this:
for(m = Math.max(j-1,0) ; m <= Math.min(j+1,grid.length-1) ; m++)
for (p = Math.max(i-1,0) ; p <= Math.min(i+1, grid[m].length-1) ; p++)
n += !(m == j && p == i) && !!grid[m][p];
How about this for your solution?
for (dj = -1; dj <= 1; ++dj) {
for (di = -1; di <= 1; ++di) {
if ((dj || di) && grid[j+dj] && grid[j+dj][i+di]) {
n++;
}
}
}
If you refactor all those ifs into a single loop like the above, then having to do the extra conditional is not so bad.

Categories

Resources