How to check null objects in jQuery - javascript

I'm using jQuery and I want to check the existence of an element in my page. I have written following code, but it's not working:
if($("#btext" + i) != null) {
//alert($("#btext" + i).text());
$("#btext" + i).text("Branch " + i);
}
How do I check the existence of the element?

Check the jQuery FAQ...
You can use the length property of the jQuery collection returned by your selector:
if ( $('#myDiv').length ){}

(Since I don't seem to have enough reputation to vote down the answer...)
Wolf wrote:
Calling length property on undefined
or a null object will cause IE and
webkit browsers to fail!
Instead try this:
// NOTE!! THE FOLLOWING IS WRONG; DO NOT USE! -- EleotleCram
if($("#something") !== null){
// do something
}
or
// NOTE!! THE FOLLOWING IS WRONG; DO NOT USE! -- EleotleCram
if($("#something") === null){
// don't do something
}
While it is true that calling the length property on an undefined or null object will cause browsers to fail, the result of jQuery's selectors (the $('...')) will never be null or undefined. Thus the code suggestions make no sense. Use one of the other answers, they make more sense.
(Update 2012) Because people look at code and this answer is pretty high up the list: For the last couple of years, I have been using this small plugin:
jQuery.fn['any'] = function() {
return (this.length > 0);
};
I think $('div').any() reads better than $('div').length, plus you won't suffer as much from typos: $('div').ayn() will give a runtime error, $('div').lenght will silently most likely always be falsy.
__
Edits november 2012:
1) Because people tend to look at code and not read what is said around the code, I added two big caveat lector notes to the quoted code of Wolf.
2) I added code of the small plugin I use for this situation.

The lookup function returns an array of matching elements. You could check if the length is zero. Note the change to only look up the elements once and reuse the results as needed.
var elem = $("#btext" + i);
if (elem.length != 0) {
elem.text("Branch " + i);
}
Also, have you tried just using the text function -- if no element exists, it will do nothing.
$("#btext" + i).text("Branch " + i);

jquery $() function always return non null value - mean elements matched you selector cretaria. If the element was not found it will return an empty array.
So your code will look something like this -
if ($("#btext" + i).length){
//alert($("#btext" + i).text());
$("#btext" + i).text("Branch " + i);
}

In jQuery 1.4 you get the $.isEmptyObject function, but if you are forced to use an older version of jQ like us poor Drupal developers just steal use this code:
// This is a function similar to the jQuery 1.4 $.isEmptyObject.
function isObjectEmpty(obj) {
for ( var name in obj ) {
return false;
}
return true;
}
Use it like:
console.log(isObjectEmpty(the_object)); // Returns true or false.

What about using "undefined"?
if (value != undefined){ // do stuff }

no matter what you selection is the function $() always returns a jQuery object so that cant be used to test. The best way yet (if not the only) is to use the size() function or the native length property as explained above.
if ( $('selector').size() ) {...}

if ( $('#whatever')[0] ) {...}
The jQuery object which is returned by all native jQuery methods is NOT an array, it is an object with many properties; one of them being a "length" property. You can also check for size() or get(0) or get() - 'get(0)' works the same as accessing the first element, i.e. $(elem)[0]

use $("#selector").get(0) to check with null like that. get returns the dom element, until then you re dealing with an array, where you need to check the length property. I personally don't like length check for null handling, it confuses me for some reason :)

Using the length property you can do this.
jQuery.fn.exists = function(){return ($(this).length < 0);}
if ($(selector).exists()) {
//do somthing
}

when the object is empty return this error:
Uncaught TypeError: Cannot read property '0' of null
I try this code :
try{
if ($("#btext" + i).length) {};
}catch(err){
if ($("#btext" + i).length) {
//working this code if the item, not NULL
}
}

if (typeof($("#btext" + i)) == 'object'){
$("#btext" + i).text("Branch " + i);
}

Calling length property on undefined or a null object will cause IE and webkit browsers to fail!
Instead try this:
if($("#something") !== null){
// do something
}
or
if($("#something") === null){
// don't do something
}

Related

How to Check the variable value is [""] in JavaScript

Example:
When I check a variable containing this value [""] it returns false.
var th=[]
th.push("");
if($("#multiselect").val()==th)
It returns always false.
Thank you.
Edit 1:
changed Var to var. It was a typo.
Edit 2:
Actually, the problem I faced was I was trying to get the value from a multi-select input. The multi-select input sometimes returns values as [""] even I haven't selected any values basically it's a plugin. So I was confused and I thought [""] is a fixed primitive value like 1, 10, "bla blah",.. So I tried to compare it with the same array as the right-hand side of the '=' operator.
It was stupid. Now I posted the solution to my problem and I explained my stupidity.
there are two things:
Change Var to var
You can use includes method of Array as:
var th = [] <==== chnage Var to var
th.push("");
if(th.includes($("#multiselect").val())) { <=== you can use includes method of array
// DO whatever you want
}
Make sure var is lowercased.
You are accessing th as an array, so you’ll need to specify the index of the value you are checking: th[0]
Use triple equals, too: .val()===th[0]
Double check the jquery docs if you’re still running into trouble.
Happy coding!
A couple of things to consider:
You have a typo in the code above; var is valid; Var is invalid.
Browser will aptly complain to solve this typo.
You are comparing an array to DOM value; this will always be false.
DOM is a costly process. Unless the value associated is dynamic, its better to read once, store value into a variable and continue processing instead of reading from DOM always.
You could choose to try something on these lines:
let arr = [1,2,3,4];
let domValue = $("#multiselect").val();
arr.push(5);
arr.map((el, ix) => {
if el === domValue return true; //or choose to do something else here.
});
var th=[]; //It is var not Var
th.push("");
if($("#multiselect").val()==th[0]) // change th to th[0]
I am unable to comment so having to use an answer for now. Are you trying to check if an array has any values? If so you can use
if(th.length){
// do something
}
If you want to check a normal variable for empty string you can simply use
if(th == “”){
//do something
}
I found the solution after a couple of days when I posted this question. Now I can feel how stupid this question was.
Anyway, I'm answering this question so it might help others.
Answer to my question:
When two non-primitive datatype objects(which is the Array here) are compared using an assignment operator, it compares its reference of the object. So the object creation of both arrays would be different. If I want to check the array has [""] value, I should do something like the below.
function isArrValEmptyCheck(value) {
return !value || !(value instanceof Array) || value.length == 0 || value.length == 1 && value[0] == '';
}
console.log(isArrValEmptyCheck([""]));//returns true
console.log(isArrValEmptyCheck(["value1"]));//returns false
Sorry for the late response. Thanks to everyone who tried to help me.

JS - document.querySelector() || document.querySelector() gives type error

I have the following code (dummy):
myFunction(document.querySelector('[data-param="param1"]').textContent || document.querySelector('[data-param="param2"]').textContent);
What is supposed to do is if param1 exists, use that one, else, use param2 by exploiting the use of falsy. I know this is not the best to use (see here), but it is what I came up with for my circumstances.
I attempted to make a jsfiddle to demonstrate this; however, the error is wrong, although this could just be different wording in the consoles as I am using two different browsers (don't ask).
In Firebug it says:
TypeError: document.querySelector(...) is null
and in Chrome it says:
TypeError: Cannot read property 'your-property-here' of null
I thought I had it working with document.getElementById('param1') || document.getElementById('param2') but what the jsfiddle is giving does not seem to work on either querySelector or getElementById.
I could not find anything about this on the docs, and my google searching did not find anything...
Is this a feature or a bug? Is there event a way to exploit falsy values on querySelector (or getElementById1, etc)? What would be the best way to go about doing what I want it to do?
The reason you see the error is because your first query is returning null, and thus it has no property dataset. Try this instead:
(document.querySelector('[data-example="example1"]') || document.querySelector('[data-example="example2"]')).dataset.example
Now if document.querySelector('[data-example="example1"]') is returning null, it will try document.querySelector('[data-example="example2"]') instead. You should be aware though, that if both queries return null you will still get the error.
There is no bug in javascript regarding your case. It is a bug in your code. Because either document.querySelector() or getElementById would return null if the supplied parameter doesn't match any elements in the document. Hence null.anything would throws error. You could rewrite your code like below to avoid such errors,
var res = (document.getElementById('id1') || document.getElementById('id2')).id;
And here also, if both id1 or id2 doesn't match anything then the same error would be raised. You can handle that situation also like below,
var res = (document.getElementById('id1') || document.getElementById('id2') || {}).id;
Now in this case, if there is no match then res would be undefined.
May be you should correct the code as follows;
// data attribute:
var elm1 = document.querySelector('[data-example="example1"]') || document.querySelector('[data-example="example2"]');
elm2 = document.getElementById('id1') || document.getElementById('id2');
document.getElementsByTagName('BUTTON')[0].addEventListener('click', function(e) {
try {
e.target.className += elm1.dataset.example;
} catch(e) {
document.getElementById('log').innerHTML += '<div>' + e + new Date() + '</div>';
}
});
// id:
document.getElementsByTagName('BUTTON')[1].addEventListener('click', function(e) {
try {
e.target.className += elm2.id
} catch(e) {
document.getElementById('log').innerHTML += '<div>' + e + new Date() + '</div>';
}
});

_.findWhere from underscorejs to JQuery

I am trying to implement this code: http://jsfiddle.net/wQysh/351/ in my project.
Everything is fine except for the line:
t = _.findWhere(sc, { id : Number(a.trim()) });
They have used underscorejs and I want to translate this to JQuery without using another lib.
I went through the doc and it stated:
findWhere_.findWhere(list, properties)
Looks through the list and returns the first value that matches all of the key-value pairs listed in properties.
If no match is found, or if list is empty, undefined will be returned.
But still I am confused about this since I am not sure what to return exactly (as first value). Can anyone give me a JQuery alternative to that line?
Thanks in advance..
If you don't the generic nature of _.findWhere() you can use a simple while loop, and compare the id to the numeric value of a (fiddle):
t = 0; // t is used as a counter
aValue = Number(a.trim()); // assign the value to a variable instead of iterating it
while (t < sc.length && sc[t].id !== aValue) { t++; }; // find the index where the id is the as the aValue
t < sc.length && toSet.push(sc[t]); // if t is less the sc.length we found the item in the array
If you need a findWhere without underscore try this gist.
I also used this example in my project. And also needed use JQuery instead of Underscore.
Here is my solution:
t = sc.filter(function (el) { return el.id === a });
It work perfect for me;
If you use number for ids, you can also convert a to integer
t = sc.filter(function (el) { return el.id === parseInt(a, 10) });

Unable to get property 'options' of undefined or null reference

i am getting the above error in ie 10 please give me a suggestion.it is working fine in
function getSelectedIndex(element, value) {
var selectedIndex = 0;
for(i = 0; i < element.options.length; i++) {
if(element.options[i].value == value) {
selectedIndex = i;
break;
}
}
return selectedIndex;
}
element.options.length is giving Unable to get property 'options' of undefined or null reference.please suggest me a sample code.
Edit : It was working for me when I was using IE11 with compatibility mode, but when I removed it and ran it in normal mode, the above issue occurred.
Use elements.options.indexOf(value) (assuming element is defined, which it doesn't seem to be). By the way, your current design will return zero if the first element matches or there is no match at all. If you really want to write your own version of indexOf, better to return -1 in the case of no match as it does.
actually the message gives you exactly what you need to know.
you are trying to read a property of something that does not have a value, and here it is "element" or "element.options", check the place where they are set before the function call.
for IE10 it's a strict one, it doesn't support the use of
element.options.length
instead you should use:
document.getElementById("optionsID").value
I hope this helps

How can I speed up this bit of JSON date parsing?

I am stuck using an AJAX library from about 5 years ago in this project, and it had some issues with parsing dates in JSON. I wound up rewriting its parse function to use a single regex:
return eval('(' + (enableDateParsing ? text.replace(/"(?:\\)?\/Date\((.*?)\)(?:\\)?\/"/g, "new Date($1)") : text) + ')');
This works really well, but I thought I could get a speed up if I used native JSON parsing in IE8 / chrome / ff, so I added this bit:
if (typeof JSON !== 'undefined' && typeof JSON.parse !== 'undefined') {
var nativeJsonDateParseRegex = /\/Date\(.*?\)\//g;
return JSON.parse(text, function (key, value) {
if (AjaxPro.enableDateParsing && typeof value === 'string' && value.match(nativeJsonDateParseRegex))
{
value = new Date(parseInt(value.substr(6)));
}
return value;
});
}
else // revert to eval for ie6/ie7
The reviver callback will execute once for each JSON property returned, so it has to be very fast. During a profile I've seen it's been called 170484 times, but still runs pretty fast (131.237ms). Any ideas on how to make it faster, or is this the best you can do without serious tweaking?
Your code contains a lot of constant conditions, you'll be fine with checking once whether native JSON is supported or not.
Suggestions:
check for native JSPN support at page load, and add the right function accordingly.
Drop the global flag from the regex if you do not need it
Drop regular expressions if possible, if every date always starts with "/Date(", search for it. It's much faster (see benchmark at jsperf.com)
todo: check whether parseInt can be replaced with an other method to get rid of the trailing )/.
If AjaxPro.enableDateParsing is a constant, you can remove if from AjaxPro.jsonParse and and make it a condition like the check for native JSON
Code without RE:
if (typeof JSON !== 'undefined' && typeof JSON.parse !== 'undefined') {
AjaxPro.nativeJsonDateParseRegex = /\/Date\(.*?\)\//g;
AjaxPro.dateFunc = function(key, value) {
if (typeof value === "string" && !value.indexOf("/Date(")) {
return new Date(value.substring(6, value.length-2));
}
return value;
};
AjaxPro.jsonParse = function(text) {
if (AjaxPro.enableDateParsing) {
return JSON.parse(text, AjaxPro.dateFunc);
}
return JSON.parse(text);
};
} else // revert to eval for ie6/ie7
This should be highly optimized. You might want to run some more test on your own in multiple browsers. Maybe checking for a property of a string is faster than checking its type (doubt it), thing like that.
One not so good microoptimization, but still worth giving a try.
Since your substring contains millisecond timestamp only, and no other garbage string.
You can remove the call to parseInt.
You can try typecasting with simple mathematical operation like multiplication with 1.
Might save some time if you are too keen on microoptimizations.
value = new Date(1*(value.substr(6)));
example:
a = "a:3333";
b = a.substring(2);
alert(b*2); // alerts 6666

Categories

Resources