I’m really enjoying using Ember’s pod structure to organize my project components. However, sometimes I need to access variables from one component in another. This isn’t a problem when traversing down the routes, but, if you need to access a child’s property in a parent component, it’s not quite as easy. Fortunately, Ember has an elegant way of solving this built right in with these so called “computed properties,” and they’re a lot of fun to use.
Ember.computed is a helper that returns a new property descriptor that wraps the passed computed property function. The best part is that computed properties observe changes in the passed property referenced, so it will update when there’s a change in the state.
For my purpose, I wanted to update the top navigation bar’s style when a flash notification is added. In my application, the nav and the flash are two separate components, so they couldn’t really communicate directly with each other, but I still needed to know when the flash messages was added and removed to update the navigation’s style.
Take a look at what I did to grab the first flash message, so I could style the top header.
/* components/site-navigation */
topFlashStatus: Ember.computed('flashMessages.arrangedQueue.@each', function() {
let flashQueue = this.get('flashMessages.arrangedQueue'),
firstFlash = flashQueue && flashQueue[0];
return firstFlash && firstFlash.get('type');
})
Except for the little javascript “nullSafe” checks, this is fairly clean and straightforward. Using Ember.computed makes it to easy to define properties! Within my site-navigation component, I am able to look for any updates for the flashMessages queue (I am using the ember-cli-flash addon for the notifications), then I am grabbing the first one in the queue to get its type.
To format the type of the first flash element into the appropriate className, I can define a second computed property.
/* components/site-navigation */
statusClassName: Ember.computed('topFlashStatus', function() {
let status = this.get('topFlashStatus');
return status ? `alert-${status}` : '';
})
All that’s left is to use the property statusClassName
in my handlebar template.
<nav class="top-bar {{statusClassName}}">
...
And now I have the desired behavior. With a little style and CSS transitions, it’s almost magical how well it works.
Of course, this is just scratching the surface of what we can do with computed properties. For a complete list of all the things you can do with Ember’s computed properties, like alias, match, and more, check out the docs on Ember.computed.