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