I have following code to check the object whether exists for item listing.
For testing purpose, i only have one object sub_total_0, however the script keep looping because typeof cannot determine sub_total_1 is undefined or not exists, and keep going 2,3,4,5,...
var i = 0;
while (typeof document.getElementById("sub_total_" + i) != "undefined") {
var obj_sub_total = document.getElementById("sub_total_" + i);
if (obj_sub_total != "undefined") {
if (fr.order_method_id.value == 1) {
obj_sub_total.style.visibility = "visible";
} else {
obj_sub_total.style.visibility = "hidden";
}
}
i++;
}
You have
typeof document.getElementById("sub_total_" + i) != "undefined"
and
if (obj_sub_total != "undefined") {
getElementById returns either null or an HTML element. Neither of these are the string "undefined" and the type of each of this will be "object". Thus your conditions don't make sense.
You test for truthfulness instead. An HTML element will always be true and null will always be false.
while (document.getElementById("sub_total_" + i)) {
and
if (obj_sub_total) {
Your check doesn't work because using typeof on getElementById's return value will always give you "object", because it returns null if it can't find it, and typeof null is "object".
Just check the return value directly: If there's an element, it's a "truthy" value (one that coerces to true when used as a condition); if there isn't one, null is a "falsey" value (coerces to false).
So:
while (document.getElementById("sub_total_" + i)) {
You also don't need to look it up twice, which is what you're currently doing; instead:
var obj_sub_total;
while ((obj_sub_total = document.getElementById("sub_total_" + i)) != null) {
(You don't technically need the != null there, but without it it looks a bit like you've accidentally used = where you wanted ==.)
Another alternative would be to use a class and querySelectorAll:
var list = document.querySelectorAll(".sub_total");
Then loop while i is < list.length, e.g.:
var list = document.querySelectorAll(".sub_total");
for (i = 0; i < list.length; ++i) {
var obj_sub_total = list[i];
// ...
}
Or you could do that even when using ids:
var list = document.querySelectorAll("[id^=sub_total]");
getElementById() return null if element is not found, and the type of null is object that is why your condition is not working.
You can just check whether it is a truthy value and since the while() loop validates the object there is no need for the if condition
var i = 0,
obj_sub_total;
while (obj_sub_total = document.getElementById("sub_total_" + i)) {
console.log(obj_sub_total)
if (fr.order_method_id.value == 1) {
obj_sub_total.style.visibility = "visble";
} else {
obj_sub_total.style.visibility = "hidden";
}
i++;
}
Demo: Fiddle
Related
When the page is loading for the first time, I need to check if there is an image in image_array and load the last image.
Otherwise, I disable the preview buttons, alert the user to push new image button and create an empty array to put the images;
The problem is that image_array in the else fires all time. If an array exists - it just overrides it, but alert doesn't work.
if(image_array.length > 0)
$('#images').append('<img src="'+image_array[image_array.length-1]+'" class="images" id="1" />');
else{
$('#prev_image').attr('disabled', 'true');
$('#next_image').attr('disabled', 'true');
alert('Please get new image');
var image_array = [];
}
UPDATE
Before loading html, I have something like this:
<?php if(count($images) != 0): ?>
<script type="text/javascript">
<?php echo "image_array = ".json_encode($images);?>
</script>
<?php endif; ?>
if (typeof image_array !== 'undefined' && image_array.length > 0) {
// the array is defined and has at least one element
}
Your problem may be happening due to a mix of implicit global variables and variable hoisting. Make sure you use var whenever declaring a variable:
<?php echo "var image_array = ".json_encode($images);?>
// add var ^^^ here
And then make sure you never accidently redeclare that variable later:
else {
...
image_array = []; // no var here
}
To check if an array is either empty or not
A modern way, ES5+:
if (Array.isArray(array) && array.length) {
// array exists and is not empty
}
An old-school way:
typeof array != "undefined"
&& array != null
&& array.length != null
&& array.length > 0
A compact way:
if (typeof array != "undefined" && array != null && array.length != null && array.length > 0) {
// array exists and is not empty
}
A CoffeeScript way:
if array?.length > 0
Why?
Case Undefined
Undefined variable is a variable that you haven't assigned anything to it yet.
let array = new Array(); // "array" !== "array"
typeof array == "undefined"; // => true
Case Null
Generally speaking, null is state of lacking a value. For example a variable is null when you missed or failed to retrieve some data.
array = searchData(); // can't find anything
array == null; // => true
Case Not an Array
Javascript has a dynamic type system. This means we can't guarantee what type of object a variable holds. There is a chance that we're not talking to an instance of Array.
supposedToBeArray = new SomeObject();
typeof supposedToBeArray.length; // => "undefined"
array = new Array();
typeof array.length; // => "number"
Case Empty Array
Now since we tested all other possibilities, we're talking to an instance of Array. In order to make sure it's not empty, we ask about number of elements it's holding, and making sure it has more than zero elements.
firstArray = [];
firstArray.length > 0; // => false
secondArray = [1,2,3];
secondArray.length > 0; // => true
How about (ECMA 5.1):
if(Array.isArray(image_array) && image_array.length){
// array exists and is not empty
}
This is what I use. The first condition covers truthy, which has both null and undefined. Second condition checks for an empty array.
if(arrayName && arrayName.length > 0){
//do something.
}
or thanks to tsemer's comment I added a second version
if(arrayName && arrayName.length)
Then I made a test for the second condition, using Scratchpad in Firefox:
var array1;
var array2 = [];
var array3 = ["one", "two", "three"];
var array4 = null;
console.log(array1);
console.log(array2);
console.log(array3);
console.log(array4);
if (array1 && array1.length) {
console.log("array1! has a value!");
}
if (array2 && array2.length) {
console.log("array2! has a value!");
}
if (array3 && array3.length) {
console.log("array3! has a value!");
}
if (array4 && array4.length) {
console.log("array4! has a value!");
}
which also proves that if(array2 && array2.length) and if(array2 && array2.length > 0) are exactly doing the same
optional chaining
As optional chaining proposal reached stage 4 and is getting wider support, there is a very elegant way to do this
if(image_array?.length){
// image_array is defined and has at least one element
}
You should use:
if (image_array !== undefined && image_array.length > 0)
If you want to test whether the image array variable had been defined you can do it like this
if(typeof image_array === 'undefined') {
// it is not defined yet
} else if (image_array.length > 0) {
// you have a greater than zero length array
}
JavaScript
( typeof(myArray) !== 'undefined' && Array.isArray(myArray) && myArray.length > 0 )
Lodash & Underscore
( _.isArray(myArray) && myArray.length > 0 )
You can use jQuery's isEmptyObject() to check whether the array contains elements or not.
var testArray=[1,2,3,4,5];
var testArray1=[];
console.log(jQuery.isEmptyObject(testArray)); //false
console.log(jQuery.isEmptyObject(testArray1)); //true
Source: https://api.jquery.com/jQuery.isEmptyObject/
Using undescore or lodash:
_.isArray(image_array) && !_.isEmpty(image_array)
A simple way that doesn't result in exceptions if not exist and convert to boolean:
!!array
Example:
if (!!arr) {
// array exists
}
How about this ? checking for length of undefined array may throw exception.
if(image_array){
//array exists
if(image_array.length){
//array has length greater than zero
}
}
The best is to check like:
let someArray: string[] = [];
let hasAny1: boolean = !!someArray && !!someArray.length;
let hasAny2: boolean = !!someArray && someArray.length > 0; //or like this
console.log("And now on empty......", hasAny1, hasAny2);
See full samples list:
I come across this issue quite a lot in Javascript. For me the best way to do it is to put a very broad check before checking for length. I saw some other solutions in this Q&A, but I wanted to be able to check for either null or undefined or any other false value.
if(!array || array.length == 0){
console.log("Array is either empty or does not exist")
}
This will first check for undefined, null, or other false values. If any of those are true, it will complete the boolean as this is an OR. Then the more risky check of array.length, which could error us if array is undefined, can be checked. This will never be reached if array is undefined or null, so the ordering of conditions is very important.
If you do not have a variable declared as array you can create a check:
if(x && x.constructor==Array && x.length){
console.log("is array and filed");
}else{
var x= [];
console.log('x = empty array');
}
This checks if variable x exists and if it is, checks if it is a filled array. else it creates an empty array (or you can do other stuff);
If you are certain there is an array variable created there is a simple check:
var x = [];
if(!x.length){
console.log('empty');
} else {
console.log('full');
}
You can check my fiddle here with shows most possible ways to check array.
The following is my solution wrapped in a function that also throws
errors to manage a couple of problems with object scope and all types
of possible data types passed to the function.
Here's my fiddle used to examine this problem (source)
var jill = [0];
var jack;
//"Uncaught ReferenceError: jack is not defined"
//if (typeof jack === 'undefined' || jack === null) {
//if (jack) {
//if (jack in window) {
//if (window.hasOwnP=roperty('jack')){
//if (jack in window){
function isemptyArray (arraynamed){
//cam also check argument length
if (arguments.length === 0) {
throw "No argument supplied";
}
//console.log(arguments.length, "number of arguments found");
if (typeof arraynamed !== "undefined" && arraynamed !== null) {
//console.log("found arraynamed has a value");
if ((arraynamed instanceof Array) === true){
//console.log("I'm an array");
if (arraynamed.length === 0) {
//console.log ("I'm empty");
return true;
} else {
return false;
}//end length check
} else {
//bad type
throw "Argument is not an array";
} //end type check
} else {
//bad argument
throw "Argument is invalid, check initialization";;
}//end argument check
}
try {
console.log(isemptyArray(jill));
} catch (e) {
console.log ("error caught:",e);
}
the way I found to work (comming from another language) is to make a simple function to test.
create a function that check the size of the array and pass the lenght by parameter.
isEmpty(size){
if(size==0) {
return true;
} else {
return false;
}
}
//then check
if(isEmpty(yourArray.length)==true){
//its empty
} else {
//not empty
}
You should do this
if (!image_array) {
// image_array defined but not assigned automatically coerces to false
} else if (!(0 in image_array)) {
// empty array
// doSomething
}
For me sure some of the high rated answers "work" when I put them into jsfiddle, but when I have a dynamically generated amount of array list a lot of this code in the answers just doesn't work for ME.
This is what IS working for me.
var from = [];
if(typeof from[0] !== undefined) {
//...
}
Notice, NO quotes around undefined and I'm not bothering with the length.
Probably your image_array is not array but some OBJECT with length property (like string) - try
if(image_array instanceof Array && image_array.length)
function test(image_array) {
if(image_array instanceof Array && image_array.length) {
console.log(image_array,'- it is not empty array!')
} else {
console.log(image_array,'- it is empty array or not array at all!')
}
}
test({length:5});
test('undefined');
test([]);
test(["abc"]);
In my case, array_.length always returned 0, even if it had values inside. Probably, because of non-default indexes.
So to check if array is defined we use typeof _array !== 'undefined'
And then to check if it contains any date i just simply compare it to an empty array _array !== []
in ts
isArray(obj: any)
{
return Array.isArray(obj)
}
in html
(photos == undefined || !(isArray(photos) && photos.length > 0) )
When you create your image_array, it's empty, therefore your image_array.length is 0
As stated in the comment below, i edit my answer based on this question's answer) :
var image_array = []
inside the else brackets doesn't change anything to the image_array defined before in the code
Is there a better way of doing this?
If I do this:
if(typeof someObject[bar][foo] == "function"){
// Do something
}
I get a someObject[bar][foo] is not an object error which it's referring to someObject[bar] if bar does not exist. This means that the code assumes you know that someObj[bar] is defined. So my solution was was this:
if(typeof someObj[bar] === "object"){
if(typeof someObject[bar][foo] == "function"){
// Do something
}
}
If we want to make an effort to reduce code lines and to make good, clean, readable code then looks redundant and ugly. Is there a better way of doing this without having to go through two if points? I realize that it's not that big of a deal, but I'm wondering if there is a better way.
I'm afraid there's no simple explanation.
In which circumstance/situation do you expect an object to behave conditionally? To give you an example of what I use ... to go advanced ... and in an attempt to go as simple as possible at the same time ...
Are you looping through a whole set of array like objects?
Can you trust the object so you already know what to expect?
object comparison for different data types?
.[I need some editing :s]
/**
* #description Get an object from a list of objects by searching for a key:value pair
* #param {Object} obj : -literal, json
* #param {String} val : the value you seek
* #param {String} key : the key
* #param {Boolean} isTypeComparison : if set to true, the key and value will be checked against it's type as well
*/
getObjectProperty: function (obj, val, key, isTypeComparison) {
var property, o;
for (property in obj) {
if (obj.hasOwnProperty(property)) {
if (typeof obj[property] === 'object') {
o = this.getObjectProperty(obj[property], val, key);
if (o) {
break;
}
} else {
// found a property which is not an object
if (isTypeComparison) {
if (property === key && obj[property] === val) {
// we got a match
o = obj;
break;
}
} else {
if (property == key && obj[property] == val) {
// we got a match
o = obj;
break;
}
}
}
}
}
return o || undefined;
},
To add some sort of value to your question, in all these loops above you see a struggle to an expectation. I've used this code to search through an ajax contact list, attached to a list. So you definitely need to write more code to meet depth and trust requirements.
If you generalize your problem, you're basically asking if you can verify a sort of 'path' in an object as being legitimate. The way I would do this is with an a function that takes the object and the desired 'path':
function has(obj, path){
var temp = obj;
var path = path.split('.');
for(var i = 0; i < path.length; i++){
if(temp[path[i]])
temp = temp[path[i]];//path still exists
else
return false;//path ends here
}
return true;//the whole path could be followed
}
This example uses a path passed as 'bar.foo' but you could easily adjust for an array ['bar','foo'] or so that it is a variable amount of arguments passed in.
This would make your example:
if(has(someObject, bar + '.' + foo)){
if(typeof someObject[bar][foo] == "function"){
// Do something
}
}
While this doesn't reduce this example in specific, if you had a much longer path to search, this could significantly reduce if statements chained together.
You could modify the function so that it returns the value specified by the path should it exist instead of true so that you only deal with one line:
function get(obj, path){
var temp = obj;
var path = path.split('.');
for(var i = 0; i < path.length; i++){
if(temp[path[i]] !== undefined)
temp = temp[path[i]];//path still exists
else
return undefined;//path ends here
}
return temp;//the whole path could be followed
}
if(typeof get(someObject, bar + '.' + foo) === 'function'){
//do something
}
if( someObject.bar && someObject.bar.foo && typeof someObject.bar.foo === "function" ){
...
}
or the same but with the better visibility notation style:
if( someObject.bar
&& someObject.bar.foo
&& typeof someObject.bar.foo === "function" ){
...
}
In the following code sample, typeof item === "undefined" never returns true. i am trying to get an attribute from XML, if the attribute is not there in the XML it returns "undefined", but i am not able to capture whether it has returned undefined or not, firebug shows "typeof item" as an "object"
var item;
var itemIDs = {};
if (items.status == 200)
{
var rows = items.responseXML.getElementsByTagName('z:row');
for(i=0;i<rows.length;i++)
{
//rows[i].attr(attribute);
item = rows[i].getAttribute(attribute);
if(typeof item === "undefined")
{
continue;
}
else
{
item = item.match(/[^\d+;#][\w\W]+/);
itemIDs[item] = 1 ;
}
}
}
else
{
alert('There was an error: ' + items.statusText);
}
return itemIDs;
Edit: I changed the condition to if(item == undefined), The code now works as expected now
Edit2: Double checked it, item variable was never null , it was "undefined"
getAttribute returns an object (valid object or a null object). So the check (typeof item === "undefined") is not correct. It should be (item === null).
Some browser's implementation of getAttribute may return an empty string if the attribute doesn't exist. You could test for both null and "", or alternatively use hasAttribute.
if(rows[i].hasAttribute(attribute))
{
// do stuff...
}
https://developer.mozilla.org/en/DOM/element.getAttribute
It's because typeof null === 'object' (contrary to the common sense). You should check if getAttrbiute's return value equals null.
item = rows[i].getAttribute(attribute);
if (item == null) { /* ... */ }
typeof null is "object"... this is what getAttribute seems to return when the attribute is missing. See documentation of element.getAttribute, specifically the notes section. It is suggested that you can use hasAttribute.
try this:
if (!item)
{
continue;
}
else
{
item = item.match(/[^\d+;#][\w\W]+/);
itemIDs[item] = 1 ;
}
this proofs if the item is null or undefined. is this true, it continues the loop.
getAttribute : return type object
you should compare return value to null
I use an object to check that a group of radio buttons have a precise value like set on "rule" object. Here is an example:
arr = {a:"1", b:"1", c:"1", c:"2"}; //that's my object rule
var arr2={}; //here I create my second array with charged value
$("#form_cont input:checked").each(function()
{
arr2[$(this).attr("name")]=$(this).val();
});
//here I make the check
for (k in arr2)
{
if (typeof arr[k] !== 'undefined' && arr[k] === arr2[k])
{
$("#form_cont li[name$='"+k+"']").css('background-color', '');
}
else
{
$("#form_cont li[name$='"+k+"']").css('background-color', 'pink');
}
}
The problem is when I have to check the "c" key I get last the one (2) and not the right value how that may e 1 or 2
thanks in advance
ciao, h.
In order to have more than one value, arr's property c will need to be an array:
arr = {a:["1"], b:["1"], c:["1","2"]}; //that's my object rule
Of course, your validity check must also change to search the new array:
typeof arr[k] !== 'undefined' && contains(arr[k], arr2[k])
...
function contains(a, obj){
for(var i = 0; i < a.length; i++) {
if(a[i] === obj){
return true;
}
}
return false;
}
You cannot have two properties on an object that are named the same. Thus when the javascript compiler sees the line arr = {a:"1", b:"1", c:"1", c:"2"}; it automatically changes it to arr = {a:"1", b:"1", c:"2"}; letting the last definition of c overwrite the first one
I'm working with JQuery to determine if an array, built earlier, with a determined number of indexes, is full or not.
When created, array looks like this :
,,,,,,
All I want to do is find if every position is filled or not.
So bascially, i'm trying to test if and only if
[x,x,x,x,x,x]
For example, if
[x,x,x,,x,x] or if [x,,,,,] //return false, wrong...
Thanks a lot.
You don't need any specific jQuery stuff to read the size of an array. Just vanilla javascript has what you need.
var arrayMaxValues = 4;
var testArray = [1,2,3,4];
if ( testArray.length == arrayMaxValues )
{
alert( 'Array is full!' );
}
else if ( testArray.length > arrayMaxValues )
{
alert( 'Array is overstuffed!' );
} else {
alert( 'There's plenty of room!' );
}
EDIT
Ah, you re-typed your question. So, you want to see if they array has zero null or undefined values?
function isArrayFull( arr )
{
for ( var i = 0, l = arr.length; i < l; i++ )
{
if ( 'undefined' == typeof arr[i] || null === arr[i] )
{
return false
}
}
return true;
}
If you fill your initial array with nulls, like:
const arr = Array(9).fill(null);
Then you can use some() or every() like this:
// check if a null doesn't exist
!arr.some(element => element === null)
// check if every element is not null
arr.every(element => element !== null)
Use whichever you like, since both of them breaks the loop when a null is found.
I know this is doing the same as Peter Bailey's function, but I only wanted to share it since it's a different approach using the built-in power of array filtering.
So, since the full array has a predetermined length you could filter it against 'undefined' and null and compare lengths, like this:
function isArrayFull(arr) {
return arr.length === arr.filter(function(o) {
return typeof o !== 'undefined' || o !== null;
}).length;
}