The following jQuery in my module gives an error that breaks LOTS of other javascript on other modules on the page. I want to know why. Why?

 var pid = $('input[name="product_id"]').attr('value');
 if ( pid.length )
   // do stuff                              

But this works fine:

var pid = $('input[name="product_id"]').attr('value');
if ( typeof(pid) !== 'undefined' )
  // this works fine

I've been using the first example for years in other environments to test for the existence of an object and it always works. What am I missing?


1 Answer 1

if (pid.length)

causes a reference error in your script if pid is undefined. So, if you don't know that pid exists ahead of time, then you have to check to see if that object is valid before trying to reference properties on it.

FYI, you could probably just use:

if (pid)

because that would protect you from pid being undefined or an empty string.

It has been raised in comments that maybe you're actually just trying to test for the existence of a DOM object, not the attribute. If that's the case, then you should just be doing this:

if ($('input[name="product_id"]').length)

which tells you if the selector matched any DOM objects.

  • jQuery returns an array with referenced objects, so @jchwebdev would want to test the length of that rather than the length of a property. So OP should be calling: if($(selector).length){var x = $(selector).property(param);} Nov 21, 2014 at 4:06
  • @murraybiscuit - .attr() returns the attribute (usually a string) or undefined. That's what the OP is testing. And, jQuery usually returns a jQuery object which has a list of DOM objects and some other properties in it (it isn't actually an array).
    – jfriend00
    Nov 21, 2014 at 4:10
  • sure, I get that, but he said in his OP he's been using the first line to test the existence of an object in the past. The problem here is that he's not testing for an object, he's assuming an object and testing a property of its attribute. Which will throw an error. Nov 21, 2014 at 4:20
  • 1
    @murraybiscuit - point taken. I read the question a little bit differently than you, but I added something to my answer in case what they really wanted to know is if there were any matching DOM objects. FYI, the OP's code still works even if the selector doesn't match anything because .attr() runs on an empty jQuery object and just returns undefined.
    – jfriend00
    Nov 21, 2014 at 4:29
  • Sorry, I thought this was a ubiquitous technique. I'm testing for the attribute -not- merely the DOM object. This works fine in other environments (eg. Wordpress since jQuery 1.4 I think.) I just wondered if there was something unique to the Drupal jQuery wrapper... and if so... if there is a document which describes the differences so I can avoid other traps. I think @murraybiscuit is probably correct... one should check for the object and -then- the attr. but apparently some environments are more 'forgiving'.
    – jchwebdev
    Nov 21, 2014 at 6:07

Not the answer you're looking for? Browse other questions tagged or ask your own question.