How to check for {} value in JavaScript? - javascript

For some reason in the code below the currentRow.cells returns {}. How can I check for that? I do not want to execute lines if the currentRow.cells returns {}.
currentRow = document.createElement("TR");
if(currentRow.cells.length > 0) { .. do something }
UPDATE 1:
All I want is to check for empty object. if the currentRow.cells is an empty object then do nothing.

I always get an object of type HTMLCollection.
You should be able to then check the length of the collection using code like this:
if(currentRow.cells.length != 0) {
//row and cells exist, work with them
}

jQuery has a helper method called $.isEmptyObject().
Their code for this is simple:
function isEmptyObject( obj ) {
for ( var name in obj ) {
return false;
}
return true;
}
If you don't want to use the whole jQuery library, you can snag this method and drop it somewhere in your own code base!

To answer your question in the title:
function is_empty(obj) {
for(var i in obj) {
if(obj.hasOwnProperty(i))
return false;
}
return true;
}
alert(is_empty({})); // true

currentRow is a <tr> (or a HTMLTableRowElement), and currentRow.cells is a HTMLCollection (not an Array ([]) or an object ({})).
If currentRow.cells is undefined, that means that current row isn't a <tr>, it's another element.
To check if a DOM element is empty, you can use childNodes (this will never be undefined).
if(currentRow.childNodes.length === 0){
// empty
}
else{
// not empty
}
Edit: Better yet, you can use hasChildNodes.
if(!currentRow.hasChildNodes()){
// empty
}
else{
// not empty
}

cells property isn't available in <tr> on IE8 and below. A workout is to use childNodes as suggested above. The following code checks if cells is undefined:
var currentRow = document.createElement("TR");
if (typeof currentRow.cells === "undefined") {
// use currentRow.childNodes
}
else {
// use currentRow.cells
}

Related

JavaScript throws TypeError saying that my variable is undefined

I don't have much experience in JavaScript, so far I have this:
function loop() {
var authorDivs = document.getElementById('ctl00_MainContent_MCPObjectInfo_dvCreatorView').getElementsByTagName("div");
for (var i = 0; i < authorDivs.length; i++) {
var divOfDiv = authorDivs[i].getElementsByTagName("div");
if (typeof divOfDiv.item(i) === 'undefined' || divOfDiv.item(i) === null) {
console.log("This is undefined or null");
}
else {
var realDivs = divOfDiv.item(i);
realDivs.item(i).textContent = "please work plz";
}
}
}
I get the following error from the console in FireFox: TypeError: realDivs is undefined on this line: realDivs.item(i).innerHTML = "please work plz";
Essentially what I have (in my mind) is a loop that goes through authorDivs and gets all of the divs within those divs and saves them in divOfDiv. I then check to see if the divs in divOfDiv are undefined or null, if they are not then those divs get saved in a variable realDivs which I then use to edit the innerHTML. That's what I'd ideally like to see happen, what is causing the error? What am I doing wrong?
Note: I do not have access to jQuery but only JavaScript.
Edit: I've added the changes suggested below and its fixed that -- thanks! But I'm now getting the following error: TypeError: realDivs.item is not a function
What is causing that? And on another note how do I know when I'm dealing with an array and when I'm dealing with an HTMLCollection? Do you just assume? I've never used a loosely typed language before so its new to me.
Well, you'll need to move that code inside the conditional block that is supposed to prevent it! Also, || "null" is not going to work as you expect, you'll need to check for || divOfDiv.item(i) === null explicitly.
So try
for (var i = 0; i < authorDivs.length; i++) {
var divOfDiv = authorDivs[i].getElementsByTagName("div");
if (divOfDiv.item(i) == null) {
console.log("This is undefined or null");
} else {
var realDivs = divOfDiv.item(i)
realDivs.item(i).innerHTML = "please work plz";
console.log(divOfDiv.item(i));
}
}
However, that still doesn't really work for two reasons:
The i index you use to access the i-th divOfDiv comes from the iteration over authorDivs - hardly what you want. Instead, use a second loop over all divOfDivs.
Your realDivs variable does hold a single <div>, which does not have an .item method. You'd just directly access its .innerHTML property.
So you should use
var authorDivs = document.getElementById('authorView').getElementsByTagName("div");
for (var i=0; i<authorDivs.length; i++) {
var divsOfDiv = authorDivs.item(i).getElementsByTagName("div");
for (var j=0; j<divsOfDiv.length; j++) {
var realDiv = divsOfDiv.item(j);
realDiv.innerHTML = "please work plz";
console.log(realDiv);
}
}
it will happen in case when your if (typeof divOfDiv.item(i) === 'undefined' || 'null') returns true. Then you never initialize realDivs (what would happen if condition was falsy). Later you try to call item function on that unitialized object
There are two problems in the code.
comparing DOM object with 'undefined' and null. If div tag is not available in authorDivs[i], it will return empty DOM array. So, comparision of empty DOM array with undefined and null is not good approach. We can use array length property for doing validation.
divOfDiv = authorDivs[i].getElementsByTagName("div");
if(divOfDiv.length > 0) { console statement}
As item(i) is already return single DOM element, item(i) of "realDivs" variable is not proper approach. In addition to this, innerHTML method needs to be used after validating whether realDivs contains DOM element. Please update the code as below.
var realDivs = divOfDiv.item(i);
realDivs ? (realDivs.innerHTML = "please work plz"): null;
Note : item(i) will return null if DOM is not available.

Check if item already exists in json array by matching ID

So I've this shopping cart, as JSON.
[{"tuote":{"id":"2","name":"Rengas 2","count":16,"price":"120.00"}},{"tuote":{"id":"1","name":"Rengas 6","count":"4","price":"25.00"}},{"tuote":{"id":"4","name":"Rengas 4","count":"4","price":"85.00"}}]
Formatted here.
So, I want to prevent from having the same value in there twice, and match them by their ids.
This is my current solution (buggy as a cockroach, doesn't really do the job), as the only time it works is when the matching value is first in the JSON string.
for (var i = 0; i < ostoskori.length; i++) {
if (ostoskori[i].tuote.id == tuoteID) {
addToExisting(tuoteID, tuoteMaara); //this doesn't matter, it works.
break //the loop should stop if addToExisting() runs
}
if (ostoskori[i].tuote.id != tuoteID) {
addNew(tuoteID, tuoteNimi, tuoteMaara, tuoteHinta); //this doesn't matter, it works.
//break
//adding break here will stop the loop,
//which prevents the addToExisting() function running
}
}
ostoskori is the json if you're wondering. As you can probably see, for each item the JSON has inside it, the more times addNew() will run.
So basically, if the JSON has a value with the same id as tuoteID, addToExisting() should run. If the JSON doesn't have a value same as tuoteID, run addNew().
But how?
You could use some to check if the id already exists. The beauty of some is:
If such an element is found, some immediately returns true.
If you're catering for older browsers there's a polyfill at the bottom of that page.
function hasId(data, id) {
return data.some(function (el) {
return el.tuote.id === id;
});
}
hasId(data, '4'); // true
hasId(data, '14'); // false
So:
if (hasId(data, '4')) {
addToExisting();
} else {
addNew();
}
Fiddle

Jquery: create a javascript method called 'containsBlanks' that returns true if any inputs with class 'required' has an empty string in, false if not

I can't seem to quite figure this one out; not sure if I'm even providing a test
condition; Also, "blanks" variable is to hold the value of the elements with the".required" class during the loop.
function containsBlanks(){
var blanks = new Array();
$required.each(function(){
blanks.($(this).val() == "");
});
return(true);
}
Loop over your Nodes and check their value against ""..
function containsBlanks() {
var i, req = $('.required');
for (i = 0; i < req.length; ++i)
if (req[i].value === '')
return true;
return false;
}
If I understand you can do this like:
$('input.required').filter(function(){ return !this.value });
That will give you all required inputs that have an empty value (if any). Then you can check the length property to find out if there are any elements in that collection.

How to determine if object is in array?

I have a javascript array that looks like this:
myFields = [
["fb-method","drop",false,"How did you order?"],
["fb-date","calendar",false,""],
["fb-time","drop",false,""],
["fb-location","drop",false,""],
["fb-amount","text default",false,""],
["fb-share","drop",false,""],
["fb-msg","textarea",true,""],
["next-btn","button",true,""]
]
I'm able to loop through the array and deal with specific bits like this:
len = fields.length;
//first check to make sure required fields are filled in
for(i=0; i<len; i++) {
a = fields[i];
if(a[0] != "fb-method") {
// do stuff
}
}
I need to be able to (outside the loop) do something if a specific element isn't part of the array, specifically one that looks like this:
["fb-location","drop",false,""]
I've tried using jQuery's .inArray function, but it returns true even when it should return false. See fiddle here.
What's the best way to go about this? jQuery or standard js is fine.
$.inArray does not return a bool, it returns the index (if no match exists, it returns -1). You would want this statement (based on your jsfiddle):
if(jQuery.inArray("fb-location", tmp) > -1) {
alert("it exists");
}
else {
alert("it doesn't exist");
}
DEMO:
http://jsfiddle.net/azWLC/2/
UPDATE:
As mentioned in the comments, this is only a half solution since the array is multidimensional. I recommend first using $.map():
var tmp = [
["fb-method","drop",false,"How did you order?"],
["fb-date","calendar",false,""],
["fb-time","drop",false,""],
["fb-amount","text default",false,""],
["fb-share","drop",false,""],
["fb-msg","textarea",true,""],
["next-btn","button",true,""]
];
var values = $.map(tmp, function(n, i){
return n[0];
});
if(jQuery.inArray("fb-location", values) > -1) {
alert("it exists");
}
else {
alert("it doesn't exist");
}
DEMO:
http://jsfiddle.net/azWLC/4/
jquery.inArray returns the index of the element. If it is not found it returns -1.. And any number except 0 is true and hence it says 'it exists'
Besides $.inArray you could use Array.filter on tmp this way:
if( tmp.filter(function(a) {return -~a.indexOf('fb-location');}).length ) {
// exists
}
JsFiddle
See also: Array.filter, Array.indexOf
Using JQuery, you'd use the JQuery grep method
if(  $.grep(tmp,function(a) {return -~a.indexOf('fb-location');}).length ) {
// exists
}

Is there a way that I can check if a data attribute exists?

Is there some way that I can run the following:
var data = $("#dataTable").data('timer');
var diffs = [];
for(var i = 0; i + 1 < data.length; i++) {
diffs[i] = data[i + 1] - data[i];
}
alert(diffs.join(', '));
Only if there is an attribute called data-timer on the element with an id of #dataTable?
if ($("#dataTable").data('timer')) {
...
}
NOTE this only returns true if the data attribute is not empty string or a "falsey" value e.g. 0 or false.
If you want to check for the existence of the data attribute, even if empty, do this:
if (typeof $("#dataTable").data('timer') !== 'undefined') {
...
}
if (typeof $("#dataTable").data('timer') !== 'undefined')
{
// your code here
}
In the interest of providing a different answer from the ones above; you could check it with Object.hasOwnProperty(...) like this:
if( $("#dataTable").data().hasOwnProperty("timer") ){
// the data-time property exists, now do you business! .....
}
alternatively, if you have multiple data elements you want to iterate over you can variablize the .data() object and iterate over it like this:
var objData = $("#dataTable").data();
for ( data in objData ){
if( data == 'timer' ){
//...do the do
}
}
Not saying this solution is better than any of the other ones in here, but at least it's another approach...
Or combine with some vanilla JS
if ($("#dataTable").get(0).hasAttribute("data-timer")) {
...
}
All the answers here use the jQuery library.
But the vanilla javascript is very straightforward.
If you want to run a script only if the element with an id of #dataTable also has a data-timer attribute, then the steps are as follows:
// Locate the element
const myElement = document.getElementById('dataTable');
// Run conditional code
if (myElement.dataset.hasOwnProperty('timer')) {
[... CODE HERE...]
}
You can use jQuery's hasData method.
http://api.jquery.com/jQuery.hasData/
The primary advantage of jQuery.hasData(element) is that it does not create and associate a data object with the element if none currently exists. In contrast, jQuery.data(element) always returns a data object to the caller, creating one if no data object previously existed.
This will only check for the existence of any data objects (or events) on your element, it won't be able to confirm if it specifically has a "timer" object.
If you want to distinguish between empty values and missing values you can use jQuery to check like this.
<div id="element" data-foo="bar" data-empty=""></div>
<script>
"foo" in $('#element').data(); // true
"empty" in $('#element').data(); // true
"other" in $('#element').data(); // false
</script>
So from the original question you'd do this.
if("timer" in $("#dataTable").data()) {
// code
}
You can create an extremely simple jQuery-plugin to query an element for this:
$.fn.hasData = function(key) {
return (typeof $(this).data(key) != 'undefined');
};
Then you can simply use $("#dataTable").hasData('timer')
Gotchas:
Will return false only if the value does not exist (is undefined); if it's set to false/null it hasData() will still return true.
It's different from the built-in $.hasData() which only checks if any data on the element is set.
You can check by css attribute selection with
if ($('#dataTable').is('[data-timer]')) {
// data-timer attribute exists
}
This is the easiest solution in my opinion is to select all the element which has certain data attribute:
var data = $("#dataTable[data-timer]");
var diffs = [];
for(var i = 0; i + 1 < data.length; i++) {
diffs[i] = data[i + 1] - data[i];
}
alert(diffs.join(', '));
Here is the screenshot of how it works.
I've found this works better with dynamically set data elements:
if ($("#myelement").data('myfield')) {
...
}
Wrong answer - see EDIT at the end
Let me build on Alex's answer.
To prevent the creation of a data object if it doesn't exists, I would better do:
$.fn.hasData = function(key) {
var $this = $(this);
return $.hasData($this) && typeof $this.data(key) !== 'undefined';
};
Then, where $this has no data object created, $.hasData returns false and it will not execute $this.data(key).
EDIT: function $.hasData(element) works only if the data was set using $.data(element, key, value), not element.data(key, value). Due to that, my answer is not correct.
I needed a simple boolean to work with. Because it's undefined of not present, and not false, I use the !! to convert to boolean:
var hasTimer = !!$("#dataTable").data('timer');
if( hasTimer ){ /* ....... */ }
An alternative solution would be using filter:
if( $("#dataTable").filter('[data-timer]').length!==0) { /* ....... */ }
var data = $("#dataTable").data('timer');
var diffs = [];
if( data.length > 0 ) {
for(var i = 0; i + 1 < data.length; i++) {
diffs[i] = data[i + 1] - data[i];
}
alert(diffs.join(', '));
}
And what about:
if ($('#dataTable[data-timer]').length > 0) {
// logic here
}

Categories

Resources