I\'m building a node
scraper that uses cheerio
to parse the DOM
. This is more or a vanilla javascript question though. At one part of
There's a difference between an empty string ""
and an undefined variable. You should be checking whether or not theHref contains a defined string, rather than its lenght:
if(theHref){
// ---
}
If you still want to check for the length, then do this:
if(theHref && theHref.length){
// ...
}
You asked why it happens, let's see:
The official language specificaion dictates a call to the internal [[GetValue]]
method. Your .attr
returns undefined and you're trying to access its length.
If Type(V) is not Reference, return V.
This is true, since undefined is not a reference (alongside null, number, string and boolean)
Let base be the result of calling GetBase(V).
This gets the undefined
part of myVar.length
.
If IsUnresolvableReference(V), throw a ReferenceError exception.
This is not true, since it is resolvable and it resolves to undefined.
If IsPropertyReference(V), then
This happens since it's a property reference with the .
syntax.
Now it tries to convert undefined
to a function which results in a TypeError.
As has been discussed elsewhere, the .length
property reference is failing because theHref
is undefined. However, be aware of any solution which involves comparing theHref
to undefined
, which is not a keyword in JavaScript and can be redefined.
For a full discussion of checking for undefined variables, see Detecting an undefined object property and the first answer in particular.
You can simply check whether the element length is undefined or not just by using
var theHref = $(obj.mainImg_select).attr('href');
if (theHref){
//get the length here if the element is not undefined
elementLength = theHref.length
// do stuff
} else {
// do other stuff
}
You can check that theHref
is defined by checking against undefined.
if (undefined !== theHref && theHref.length) {
// `theHref` is not undefined and has truthy property _length_
// do stuff
} else {
// do other stuff
}
If you want to also protect yourself against falsey values like null
then check theHref
is truthy, which is a little shorter
if (theHref && theHref.length) {
// `theHref` is truthy and has truthy property _length_
}
In addition to others' proposals, there is another option to handle that issue.
If your application should behave the same in case of lack of "href
" attribute, as in case of it being empty, just replace this:
var theHref = $(obj.mainImg_select).attr('href');
with this:
var theHref = $(obj.mainImg_select).attr('href') || '';
which will treat empty string (''
) as the default, if the attribute has not been found.
But it really depends, on how you want to handle undefined "href
" attribute. This answer assumes you will want to handle it as if it was empty string.