A JavaScript equivalent to Ruby’s respond_to?

While working on the new version of Mayday, I wanted to show a message if no data was returned from Google Analytics. To add to the complexity, I wanted to be able to override the default message on a per page basis.

I’m already using the ICanHazJS client-side tempting engine which has a method for each template block on a page. However, if the page doesn’t have the block then the method won’t exist and an error will be thrown.

What I needed was functionality similar to Ruby’s respond_to. With this method I can ask the object if it will respond to the method call. For example:

Object.respond_to? ‘test’ #=> false
Object.respond_to? ‘to_s’ #=> true

Luckily this is just as easy to do in JavaScript using ‘in’

> ‘test’ in Object
false
> ‘toString’ in Object
true

This allowed me to write the following:

var e = $(‘#data’)
if(‘nodata’ in ich)
   e.append(ich.nodata());
else
   e.append(‘No Data Found’);



If a nodata ICanHaz template block appears on the page then it will be rendered, otherwise it will fall back to the default. Problem solved.


Update: 


Problem almost solved. As pointed out on Twitter by @nmosafi and @theprogrammer, just using ‘in’ along is not enough.  For example:

> Object.test = “test”
“test”
> ‘test’ in Object
true
> Object.test()
TypeError: Property ‘test’ of object function Object() { [native code] } is not a function



What you need to do is ensure that the property is also a function. Something I had assumed previously.


> ‘test’ in Object && typeof(Object.test) == “function”
false

> ‘toString’ in Object && typeof(Object.toString) == “function”
true