Hi, I want to discus the merits and downsides of my pull request some more.
Here’s the pull request:
As you can see it is closed because my use case seems better suited for a computed property.
I however respectfully disagree:
Here’s my situation, I work for a company that makes a product that listens to a variety of sensors such as rain meters, uv meters, anemometer (wind), power (electricity) and water usage meters. All these sensors send their data via radio, which is not the most reliable means of communication. So every once in a while our server does not receive data from the sensors.
When this is the case the value of that sensor becomes ‘null’. For instance the rain meter would be {rainfall: null}, and the uv meter {uvi: null}}. So ‘null’ is means ‘no data’ and the user must be able to see this in the UI… What further complicates things is that the number zero is a valid value, sometimes there is no rain, wind or the temperature is zero degrees. The normal {{if}} treats the number zero as a false value so it executes the {{else}} branch. So In my case I need an {{if}} that treats only ‘null’ as a false value.
Now I can create a computed property that only returns false when the value is ‘null’ which is a great solution. But I have 6 different kinds of sensors each with multiple properties. For instance a thermometer also has a humidity, max temperature, min temperature, min humidity and max humidity. I’ll have to program an enormous pile of computed properties. (Unless I’m missing something obvious that makes this easier, if this is the case please inform me)
My DRY solution is to create a custom if statement which checks for ‘null’ and ‘undefined’ everything else is a truthy value, including the number zero. This is a version I use for the old app that uses Ember 0.9.81:
Handlebars.registerHelper("ifData", function(property, options) {
if (property === null || property === undefined) {
return options.inverse(this);
}
var value = Ember.getPath(this, property);
if (value === null || value === undefined) {
return options.inverse(this);
}
else {
return options.fn(this);
}
});
This was taken from the handlebars website: http://handlebarsjs.com/block_helpers.html
This saves me from writing allot of computed properties, and keeps the code DRY. Now there is one problem when this approach, it is not bindings aware, when the property changes nothing is reevaluated. So if a thermometer is ‘null’ at the start and ‘22.0’ somewhere along the line ‘No Data’ is still displayed.
In my search to make my ‘ifData’ bindings aware I came across a function called ‘boundIf’ which almost did what I wanted. It defines ‘truthy’ and sends this to a private method called ‘bind’. If you change the definition of ‘truthy’ and call ‘bind’ yourself you can create your own specialized bounded if statements. The only problem is that ‘bind’ is a private method and I haven’t found a way to call it myself.
So my pull request makes ‘bound’ available as a Ember.Handlebars.helpers._bind I use it like this:
Handlebars.registerHelper("ifData", function(property, fn) {
var context = (fn.contexts && fn.contexts[0]) || this;
var func = function(result) {
if (typeof result === 'boolean') {
return result;
}
return result != undefined && result != null;
};
return Ember.Handlebars.helpers._bind.call(context, property, fn, true, func, func);
});
I agree ‘_bind’ is a bad name and it’s name probably should be changed to reflect it’s purpose better. But not giving it to the users access to it is a shame, it is really useful. Perhaps ‘bindDOM’ will make it more clear.
The main argument against this is that you can use computed properties for this case. But you can use computed properties for every helper you define in Ember. For instance the often used example of a Handlebars helper ‘capitalize’ can be expressed in a computed property.
Since Handlebars supports writing our own custom ‘block’ helpers why not Ember bounded block helpers?
So why can’t we express bounded custom {{if}} statements if it makes our code more DRY?
Thank you for reading.
PS: If you know of a way to express my case with a computed property that I can use everywhere please let me know