Why do I get "Uncaught TypeError: Cannot read property" error with this variable?

10,685

Solution 1

Both your selectors are invalid, as such they return an empty jQuery result list.

Calling .height() on an empty result list returns null. Calling .offset() on an empty result list also returns null.

The reason you get Uncaught TypeError: Cannot read property 'top' of null in the second line is because you are trying to call .top() on the result of offset() which is null.

Basically you are trying to execute null.top().

I don't know what your code is for but as a pure example you could check the results first before using them, similar to this:

var $elem1 = $('.not-here');
var $elem2 = $('.also-not-here');

if($elem1.length && $elem2.length){
    var test = $elem1.height();
    var test2 = $elem2.offset().top;

    $('#output').append('yeah');
}

Solution 2

$('.also-not-here').offset() returns null if the node doesn't exist. That is how it works by design.

As you want a fix so your code doesn't break, you can do something like this:

var $node = $('.also-not-here');
var test2 = $node.length>0 ? $node.offset().top : null;

Solution 3

var test = $('.not-here').height();

This return you null, since there's no element $('.not-here').

Again,

var test2 = $('.also-not-here').offset();

This also return you null, since there's no element $('.also-not-here') and we cannot read property top of null.

I would suggest to do this:

$.fn.isThere = function(){ return this.length > 0; }

var $selector = $('.also-not-here');
if ($selector.isThere()) {
    var test2 = $selector.offset().top;
}
Share:
10,685

Related videos on Youtube

shrewdbeans
Author by

shrewdbeans

Updated on June 04, 2022

Comments

  • shrewdbeans
    shrewdbeans almost 2 years

    In this jsFiddle I have two variables that would be either undefined or null. The script works if the first variable is initialised, but not if the second is used. You can test this by commenting out each one and running the script.

    This is the code:

    var test = $('.not-here').height(); // works with this variable
    var test2 = $('.also-not-here').offset().top; // doesn't work with this
    
    $('#output').append('yeah');
    

    Why do I have this problem and how do I get around it?

    • jahroy
      jahroy about 11 years
      You can't de-reference something that is undefined. That's all there is to it. When a jQuery selector returns no elements, jQuery still returns an empty set (ie something that IS defined). When you call .offset() on an empty set, it is undefined. So... You can't invoke a method on the return value of offset() in this case.
    • jbabey
      jbabey about 11 years
      Uncaught TypeError: Cannot read property 'top' of null
    • Dave
      Dave about 11 years
      The issue is that $('.also-not-here') actually is an (empty) list, whereas $('.also-not-here').offset() is truly undefined.
    • Dave
      Dave about 11 years
      Or to put it another way, jQuery protects you from undefined and null, but once you're out of its protection, you have to deal with it yourself.
  • fmsf
    fmsf about 11 years
    removed the -1, sorry it's really a bad practice, specially since you are giving an example to a person learning.
  • palaѕн
    palaѕн about 11 years
    I do apologize for that. I usually cache all the elements, if used more than once. Thanks for pointing it out!