Series: Computed Properties

Computed Properties-Working with Arrays

Published on Jul 26, 2015

Computed properties can be used to work arrays of data.

In this episode, we look at how to compute off of an array and off of various properties on an array using @ and {}.


Links

Code

//demonstrations/computed-getter/controller.js
import Ember from 'ember';

export default Ember.Controller.extend({
  //...
  documentaries: [
    {name: 'Iron Man 1', release: '2008', budget: 140000000, boxOffice: 318000000},
    {name: 'Iron Man 2', release: '2010', budget: 200000000, boxOffice: 312000000},
    {name: 'The Avengers', release: '2012', budget: 220000000, boxOffice: 623000000},
    {name: 'Iron Man 3', release: '2013', budget: 200000000, boxOffice: 408000000},
    {name: 'Avengers 2', release: '2015', budget: 250000000, boxOffice: 455000000}
  ],

  totalDocumentaryBudget: Ember.computed('documentaries.@each.budget', function(){
    var totalBudget = 0;
    this.get('documentaries').forEach(function(documentary){
      totalBudget += Number(documentary.budget);
    })
    return totalBudget
  }),

  totalDocumentaryProfit: Ember.computed('documentaries.@each.{budget,boxOffice}', function(){
    var totalProfit = 0;
    this.get('documentaries').forEach(function(documentary){
      totalProfit += Number(documentary.boxOffice);
      totalProfit -= Number(documentary.budget);
    })
    return totalProfit
  })
});
//demonstrations/computed-getter/template.hbs
<h1>Relevant Documentaries</h1>
{{#each documentaries as |documentary|}}
  {{input value=documentary.name}}, released in {{input value=documentary.release}} for ${{input value=documentary.budget}}, bringing in ${{input value=documentary.boxOffice}}.<br>
{{/each}}

Total budget: {{totalDocumentaryBudget}}<br>
Total profit: {{totalDocumentaryProfit}}

Transcript

In the last episode, we learned the basics of computed properties. In this episode, we’ll be working with lists and objects using some new syntax. Here’s our application from last time. We can change the first name and it computes the full name and the business card from that.

Here’s the code with the basic syntax. It’s Ember.computed and then the computed keys and then the function that returns the property. So let’s create a list that we can work with today. We’ll create a list of documentaries about this person’s life. And I know what you’re thinking, Avengers wasn’t a documentary about Tony Stark. And you’re right, but since it did illuminate parts of his life absent from other more-focused documentaries, we’re including it.

Let’s also loop through these in the template. That will allow us to change our values for when we’re calculating from them. Now we want to see how much money has been spent documenting this person’s life. So we’re going to create a computed property called totalDocumentaryBudget. It’s going to use Ember.computed, and then it will depend on each of the documentaries’ budget. So it’ll be documentaries.@each.budget. Then we’ll have our function. We’ll start with the totalBudget off at 0, we’ll loop through each documentary and add the number, add the budget to the totalBudget. Then we return the budget.

There are slightly shorter ways to do this with functional programming, but this is more understandable for a general audience. We’ll then display our computed property in the template. So let’s see this working. We have our total budget and we can affect that by changing the budget, as we would hope.

Now it’s important to know what each part of this computed property key does. So documentaries, what it does is it says to watch this array. And this computed property will be triggered whenever the array is set to something new or an item is added or removed from the array. In older versions of Ember, you may have to use this syntax to get that effect. Then the @each, it tells us to watch each of these individual items in the array.

As it is right here, it will recompute the computed property when one of these is changed to wholesale, so if it replaces it with another object. In order to get it to change whenever a property on that object is changed, you need to add in something like budget. So this is now watching the budget property of each item in the array.

There’s one last thing to note before we move on to our next piece of syntax, and it’s that you can’t use @each more than once in a computed property key. So let’s say for example that that budget wasn’t a number. Instead, it was an itemized list of expenses. So then you might try to do say @each and then cost. So if we had say like five expenses per budget and only five documentaries, that’ll be fine, but lists invariably grow. And say we get 100 documentaries and then 100 itemized expenses per budget, you can see how that can quickly get out of hand because each list is 20 times longer, but the computation will take 400 times as long, and it will happen 400 times as often most likely. So you’re only allowed to use @each once in a key.

Now let’s say that we wanted to calculate not just the total budget for all these documentaries. We also wanted to calculate the total profit. So here’s the basic part of it. It’s very similar to budget. You start off with the profit of zero, you add in the boxOffice and you subtract the budget for each of the documentaries, and then you return the totalProfit. However, we don’t need to watch just the budget for each one. We’ll also need to watch the total boxOffice.

Now we can do it like this with two separate keys, but there’s an easier way to do it. We can use this syntax. So this will have the same effect as listing the two keys separately, and you can put as many properties as you want inside these curly braces, and they’ll branch off as if you had listed each of them separately. Note that there can’t be any spaces, so this would be an incorrect syntax. This is correct. We’ll add this to our template, and then we’ll see it in action. We can see that the total profit changes whenever we change either the budget or the box office.

So in this episode, we learned how to use the @ symbol and the curly braces withinside your computed property keys in order to better work with lists. In the upcoming weeks, we’ll have more stuff about computed properties. So I hope to see you then.

Computed Properties

Subscribe to our mailing list