Ember 2.0 Class Helpers

Published on Nov 13, 2015

In Ember 1.13, a more powerful version of Handlebars Helpers was introduced: Class Helpers. Within these new helpers, you can access services and recompute the value at will.

Today’s episode shows how to upgrade our example helper with information from currency conversion service.


Links

Code

Call with Ember.Helper.extend({}). Helper will output return value of compute function. this.recompute() will recompute.

The price helper:

import Ember from 'ember';

export default Ember.Helper.extend({
  yenConverter: Ember.inject.service(),
  compute(params, {price}) {
    var symbol = this.get('yenConverter.isInDollars') ? '$' : '¥';
    var convertedPrice = this.get('yenConverter').exchange(price);
    var roundedPrice = Math.round(convertedPrice * 100)/100
    return Ember.String.htmlSafe(`<b>${symbol}${Ember.Handlebars.Utils.escapeExpression(roundedPrice)}</b>`);
  },
  recomputeWhenChanged: Ember.observer('yenConverter.currentCurrency', 'yenConverter.exchangeRate', function(){
    this.recompute()
  })
});

Calling the helper:

{{price price=monster.price}}

Transcript

So in the last episode, we introduced the Ember. JS Helper API, specifically the new version that was introduced in 1.13, and we used it to display the prices. So we have our helper that... it adds a bold thing around it, and then a dollar sign, and then it makes sure the price is safe and it does some stuff to make sure everything displays correctly. And then we can use that, and every time we use the price helper we automatically get that bold and that dollar sign and our price. That’s pretty nice but it’s not the full power of helpers.

So the full power of helpers, you can call services and you can use the compute and recompute methods. To do that we’re going to have to do a class helper, and I’ll show you how to do that today.

So we’ll start off by taking this same functionality and just doing it in a class helper. So instead of Helper.helper, we’re going to be doing Helper.extend, and then we’re going to have the compute method on that class. Within that compute method we’re going to be doing the same thing as we did up in price, and so we’ll just copy and paste that in there and we’re good to go.

We can see that everything is still displaying as it should. So like our function before, the compute helper takes the params and then a hash of params, and then it returns something, and whatever is returned from the compute helper is what it is displayed in the template.

So now let’s add to our functionality. We want to be able to display our prices in yen as well as dollars since our business is moving partly to Japan. So luckily we made a yenConverter service, but how do we get that in here? Well, it’s simple. Because this is a class, we can just inject the service like we would in any other class and then we can start using it.

So we’ll start by changing the symbol. So if our yenConverter says that we’re in dollars, then it’ll show the Dollar sign. Otherwise, it’ll show the Yen sign. And we’ll insert this here.

And now since our yenConverter is in Yen, it’ll show up as yen. And we forgot the ending semicolon. Now it will show up as the Yen symbol. Then we’ll go ahead and convert the price and round it and stick that within our expression.

Then that gets us not only the Yen sign, but the price is converted into yen. So this yenConverter that we’ve used so far and our helper is great if we only want to show it in yen, but we want to be able to switch between English Dollars and Yen, so we’re going to have to do more than just inject a service. We’re going to have to find a way to change it and then recompute our helper when that value is changed.

So I’m going to quickly put in a little row here that shows the currency and gives you a switchCurrency button, and then it shows the amount of Yen per Dollar and allows you to change it. And then to handle some of these actions, we’ll create a monsters controller and it’ll inject the yenConverter and then have a switchCurrency action which calls the switchCurrency method on the yenConverter.

So now we can change the amount of ‘Yen per Dollar’ and switch, but even though it’s switching, it’s not reflected here. That’s because this is a helper and it’s only computed at the start.

So in our helper, we’ll create the recomputeWhenChanged method. So that will take an observer and will watch both the currentCurrency and the exchangeRate. And then whenever either of those are called, we’ll call recompute. Now when we hit ‘Switch’, we’ll see that everything changes to dollars. And when we change the ‘Yen per Dollar’, it recomputes.

Let’s review our class helpers. So a class helper can do everything a function helper can, and if all you want to do is recreate that, then you just use the compute function, and you pass in the same parameters, and hash of parameters, and then you return whatever you want to show in the template. However, you’re not limited to just that. Because it’s a class you can inject services and you can recompute whenever something is changed on one of those services. If you wanted to expand this, you could do something like connect this service up to an API that will create the exchangeRate, it’ll pull it in and get it in real time. That would be really cool. Let me know what other ways you think of to make cool things with this in the comments. I’ll see you later.

Subscribe to our mailing list