<![CDATA[kevink]]>http://kevink.me/Ghost 0.7Sat, 17 Aug 2019 15:14:54 GMT60<![CDATA[Contextual Components in Ember]]>http://kevink.me/2016/01/19/contextual-components-in-ember/4840a1c8-a5f8-4fae-b06f-4cfd64c9b76cTue, 19 Jan 2016 17:54:35 GMT Contextual Components in Ember

Ember 2.3 has just been released and with it we're receiving an exciting enhancement to components - contextual components. The feature will be very useful when creating complex nested component structures. It's especially handy for addon developers.


Before this enhancement developers had to break component encapsulation in situations where several components were to be connected into a complex UI. For instance, we'd like to share data between nested components:

{{#some-form data=model}}
  {{some-field data=model.name}}

As you can see, we have to pass the model into the two components separately - even though our plan was for these components to be linked. The new contextual components allow us to simplify the above into something like this:

{{#some-form data=model.name as |form|}}

This is achieved by defining the some-form component's template like this:

// app/templates/components/some-form.hbs
{{yield (hash
  field=(component 'some-field' data=data)

We can now simply yield components with the use of the hash helper.

A working example

My first thought upon reading the new contextual components API was to create a tooltip/popover component. This component would yield two child components:

  • One to define the element, which - upon clicking - should reveal the popover
  • Another one to hold the content of the popover

We'll create a popover-container component with the following template and logic:

// app/templates/components/popover-container.hbs
{{yield (hash
    handle=(component 'popover-handle' click=(action 'toggle'))
    content=(component 'popover-content' isShowing=isShowing)
// app/components/popover-container.js
import Ember from 'ember';

export default Ember.Component.extend({  
  isShowing: false,

   actions: {
    toggle() {

The component has an isShowing property which can be toggled between the true and false states with the toggle() action. Its template yields a hash containing two child components:

  • popover-handle will trigger the action when clicked
  • popover-content is passed the isShowing property, so that it knows when to be displayed

The popover-handle does not need to contain any logic for this example and its template is simply {{yield}}. popover-content similarly does not have any logic, but the template is slightly modified:

// app/templates/components/popover-content.hbs
{{#if isShowing}}

Finally we can combine the above:

// app/templates/application.hbs
{{#popover-container as |popover|}}
    {{#popover.handle tagName="button"}}

We make the popover.handle component into a button, which - when clicked - will reveal or hide what's defined in popover.content. The popover-container component can share actions and data with its child components quite easily!

Here's an Ember Twiddle if you want to see this example in action: https://ember-twiddle.com/4ae6c7817d92e2cb001d


This post was not meant to be a full-blown tutorial. I just wanted to introduce a great new feature, which should make our web applications better and easier to maintain and develop.

Ember just keeps getting better and better!

<![CDATA[A Task Manager with Alerts in Ember]]>http://kevink.me/2015/12/28/a-task-manager-with-alerts-in-ember/ec83826a-ee5b-409d-895f-f008721ae9a1Mon, 28 Dec 2015 11:20:00 GMT A Task Manager with Alerts in Ember

A while ago I read this article on architecture in Ember apps. In one of the examples - monitoring background tasks - the author suggests creating a service that would be coupled with some components to display and manage arbitrary tasks.

I thought this was an interesting idea and decided to try and implement such a solution. In this post I will show my approach and explain how it works.

Feel free to check out the repository if you're interested in the finished product.

What to expect

In this short tutorial we will create an Ember Service for holding a collection of Tasks. This service will be connected with two components:

  • a component for showing alerts on finished tasks
  • a component for showing the status of all tasks

All this will be connected to a simple input, which will allow us to start named tasks. For the sake of simplicity, the tasks in this tutorial will be simple timers that finish after a random number of seconds. In a real application the tasks could be file uploads or API calls.


We'll start by generating an empty project and adding the routes, components and service we'll need later:

$ ember new ember-task-manager-example
$ cd ember-task-manager-example
$ ember g route application
$ ember g route test
$ ember g template index
$ ember g component alerts-container
$ ember g component task-monitor
$ ember g service task-manager
$ ember g initializer task-manager

The Service

Now that we have the necessary structure, we'll implement the Task Manager service. First, we'll configure the initializer:

// app/initializers/task-manager.js
export function initialize(container, application) {  
  application.inject('route', 'taskManager', 'service:task-manager');
  application.inject('component', 'taskManager', 'service:task-manager');

export default {  
  name: 'task-manager',

The above will inject the Task Manager service into all routes and components. Thanks to this we will be able to access it simply by calling this.get('taskManager').

Next up is the actual service. Here's the code, some explanation follows below:

// app/services/task-manager.js
import Ember from 'ember';

export default Ember.Service.extend({  
  tasks: null,

  alerter: null,
  monitor: null,

  init() {
    this.set('tasks', Ember.A());

  _taskStarted(task) {
    if(this.get('monitor')) {

  _taskFinished(task) {
    task.set('finished', true);
    if(this.get('alerter')) {

  addListener(type, component) {
    this.set(type, component);
    if(type === 'monitor' && component) {
      this.get('tasks').map(task => {

  destroyListener(type) {
    this.set(type, null);

  runTask(task) {
    task.run().then(() => {

During the init() call we set the service's tasks property to an empty array - this will hold the tasks we'll be adding to it later. We have also declared 2 interesting properties: alerter and monitor. These will hold references to components - this will allow us to communicate with the components and alert them of any changes.

As mentioned before, we will introduce an alerting component and a monitor component. They register themselves in the service by calling its addListener method. This method simply assigns the component to the relevant property. Additionally, if the component in question is of type monitor, we will let it know of all tasks - thanks to this the component will be able to show all tasks even between route transitions. A component should also call destroyListener before it is destroyed, so that we don't notify nonexistent components.

A task is added to the service's queue by calling the runTask method. It accepts a task object, which should contain a run method - this method should return a promise, which will allow us to easily track its progress. Inside runTask the task is added to the queue through _taskStarted. We simply push the task into the current task list and notifies the task monitor component, if present.

After a task is finished, the _taskFinished method is called. It sets the task's finished property to true and notifies the alert component that a task has finished running. The task should have an alert object. Soon we'll see how this works in the actual components.

The Alerts Component

This component is intended to be inserted somewhere in the application template (we'll get to that later). Whenever a task finishes, the component will be notified and will display an alert. Let's look at the code:

// app/components/alerts-container.js
import Ember from 'ember';

export default Ember.Component.extend({  
  alerts: null,

  init() {
    this.set('alerts', Ember.A());
    this.get('taskManager').addListener('alerter', this);

  addAlert(alert) {

  actions: {
    removeAlert(alert) {

There's not much happening here, really. On initialization we set the alerts property to be an empty array - this will be filled up with alerts later. Furthermore, the component registers itself in the Task Manager service by calling addListener. The service can now call the component's addAlert method, which simply pushes a task's alert into the alerts array. We've also added a removeAlert action, so that we can remove an alert from the view.

Here's what the component's template looks like:

// app/templates/components/alerts-container.hbs
{{#each alerts as |alert|}}
  <div class="alert alert-info alert-dismissible" role="alert">
    <button type="button" class="close" data-dismiss="alert" aria-label="Close" {{action 'removeAlert' alert}}><span aria-hidden="true">&times;</span></button>

We simply loop through all alerts and display their message. There's also a bit of styling (I've used bootstrap for quick prototyping) and a close button, which calls the previously mentioned removeAlert action.

The Task Monitor Component

This component won't be very different from the alerting component. In fact, this could probably be done in a more flexible fashion using some kind of mixin! That would also make the service a bit more reusable (we wouldn't need to declare special alerter and monitor containers), but I decided to leave that as an exercise to the reader.

Anyhow, here's our component:

// app/components/task-monitor.js
import Ember from 'ember';

export default Ember.Component.extend({  
  tasks: null,

  init() {
    this.set('tasks', Ember.A());
    this.get('taskManager').addListener('monitor', this);

  willDestroyElement() {
    this.set('tasks', Ember.A());

  addTask(task) {

As I said, this is very similar to the alerting component. The only difference is that this task monitor will empty its tasks array and unregister itself from the task manager service whenever it's about to be destroyed. This is necessary because we'll put this component into the index route later on and will be destroyed between route transitions.

This component simply displays a list of tasks (received from the service) and their current status:

// app/templates/components/task-monitor.hbs
  {{#each tasks as |task|}}
    <li>'{{task.name}}': {{if task.finished "finished!" "loading..."}}</li>

Tying it all together

We have the components and service, but now we need to actually start using them. In our example, we'll only show the task monitor in the index route, so we'll render it there:

// app/templates/index.hbs

In the beginning we've also created a test route. We will leave it empty, as we just want to be able to transition between routes and see that:

  • alerts render under all routes
  • the task monitor receives all current tasks on creation

Now let's go to the application route:

// app/routes/application.js
import Ember from 'ember';

function getRandomInt(min, max) {  

let Task = Ember.Object.extend({  
  finished: false,
  name: null,
  run: null,
  alert: null

let Alert = Ember.Object.extend({  
  message: null

export default Ember.Route.extend({  
  clicks: 0,

  _createTask: function(name) {
    let rand = getRandomInt(1, 10);

    return Task.create({
      name: name,
      run: function() {
        return new Ember.RSVP.Promise(resolve => {
          Ember.run.later(function() {
          }, rand * 1000);
      alert: Alert.create({
        message: 'Task ' + this.incrementProperty('clicks') + ' "' + name + '" finished after ' + rand + ' seconds.'

  actions: {
    runTask: function() {
      let name = this.get('controller.name');

Most of what you see here is only required for presentation purposes - we simply want to be able to demonstrate the service and components.

The getRandomInt function returns a random integer from a specified range. We will use this below when we're generating tasks.

We also define 2 objects: a task and an alert. These are the "models". A task will have a finished property, used to inform us of its status. It also has a name (can be arbitrary), an alert (an object sent to the alerting component after the task is finished) and a run method - our task manager service expects this to return a promise.

The application route has an action which will be triggered by clicking a button: runTask. This action will create a named task and send it to the task manager service for further handling.

Creating a sample task is handled inside _createTask. This, again, is just an example required for the sake of this tutorial. Our tasks can run a promise that will resolve in a random number of seconds. We will track the number of _createTask calls in the clicks property - in this example we'll be creating multiple tasks with possibly the same name, so we want to be able to show which successive task has finished. A task also receives an alert object, which contains a message on how long the task took to finish (the random number) and which task it was.

And finally there's the application template:

// app/templates/application.hbs
<h2 id="title">Task Manager Example</h2>

<div class="container">  
  <div class="row">
    {{link-to 'index' 'index'}}
    {{link-to 'test' 'test'}}
  <div class="row">
    <div class="form-group">
      <label for="name">Task Name</label>
      {{input value=name class="form-control" id="name"}}
    <button {{action "runTask"}} class="btn btn-default" role="button">Run Task</button>
  <div class="row">
    <div class="col-xs-6">
    <div class="col-xs-6">

It contains links to our two routes: index and test, a simple input form for creating named tasks, an outlet and the alert component.

Run it

To see the example in action, we need to run Ember CLI's server:

$ ember serve

Now visit localhost:4200 and see the whole thing in action! Here's a gif of what it looks like:

A Task Manager with Alerts in Ember

We create a couple of tasks named "Test", each receiving a random number of seconds to execute. After a task is finished, an alert is displayed. While we're on the index route we're also presented with a list of all the tasks we've create with their current status.


As promised, we have created a service for managing background tasks (which could include file uploads or other long-running calls). The service is coupled with two components, so that we're able to monitor the current situation and be notified of a task finishing.

Of course, the code presented here is a very simple approach and may not be flexible enough for everyone's needs. I would like to encourage the reader to take this post as a starting point and try and improve on it as an exercise. Here's some pointers on what could be done better:

  • Track a Task's status internally, instead of setting it in the service
  • Create a mixin so that any component can register itself in the service
  • Improve the service so that any number of components can listen to its events
  • Actually hook up multiple types of actions and run them

The code for this tutorial is available in this repository and the app itself is available under http://kevinkucharczyk.github.io/ember-task-manager-example/.

I hope you've enjoyed this tutorial! Any questions or comments are, as always, very welcome.

<![CDATA[Ember Services: Logging Route Transitions]]>http://kevink.me/2015/10/30/ember-services-logging-route-transitions/7f8cde5b-fabd-403e-a5fe-a3af17474bc4Fri, 30 Oct 2015 17:06:00 GMT Ember Services: Logging Route Transitions



Ember Services: Logging Route Transitions



What are Services?





We'll start by generating a new project via Ember CLI:

$ ember new ember-logging-service



// app/router.js
import Ember from 'ember';  
import config from './config/environment';

var Router = Ember.Router.extend({  
  location: config.locationType

Router.map(function() {  

export default Router;  


Additionally, open up the application template and add the following:





The Service


$ ember g service logger


Here's the content of our service, an explanation follows below:

// app/services/logger.js
import Ember from 'ember';

export default Ember.Service.extend({  
  events: [],

  log(obj) {
    let eventObject = {
      time: new Date()

  saveLogs() {
      let log = {
        events: Ember.copy(this.get('events')),
        locale: navigator.language,
        time: new Date(),
        userAgent: navigator.userAgent
      console.log(log); // push logs to server





  • A locale property, to categorize the user's language
  • A timestamp



Initializing the Service


Let's generate an initializer:

$ ember g initializer logger


// app/initializers/logger.js
export function initialize(application) {  

export default {  
  name: 'logger',
  initialize: initialize


export default Ember.Component.extend({  
  logger: Ember.inject.service()

But we won't use this method in our example.

Logging Route Transitions





$ mkdir app/reopens
$ touch app/reopens/router.js


import Ember from 'ember';

export default Ember.Route.reopen({  
  afterModel(resolvedModel, transition) {
    this._super(resolvedModel, transition);

    if(this.routeName === transition.targetName) {
        type: 'transition',
        target: transition.targetName,
        queryParams: transition.queryParams





// app/app.js
import Ember from 'ember';  
import Resolver from 'ember/resolver';  
import loadInitializers from 'ember/load-initializers';  
import config from './config/environment';  
import Route from './reopens/route';

var App;


App = Ember.Application.extend({  
  modulePrefix: config.modulePrefix,
  podModulePrefix: config.podModulePrefix,
  Resolver: Resolver

loadInitializers(App, config.modulePrefix);

export default App;  


Try it out!


$ ember serve


Ember Services: Logging Route Transitions






Thanks for reading and see you next time!

<![CDATA[Creating a Sortable Table Component in Ember.js]]>http://kevink.me/2015/10/23/creating-a-sortable-table-component-in-ember-js/4d517c95-a36a-48fc-b75a-a4276ba9d1a3Fri, 23 Oct 2015 11:42:34 GMT Creating a Sortable Table Component in Ember.js

Sometimes in our web applications we want to display tabular data. This by itself is easy enough, but we would also want this table to be sortable AND reusable. We could just use a JS plugin we found on the web, but it's possible to do this in just a couple of lines of code in Ember.js.

In this post I will show you how to create a table component that accepts any data and has sorting built-in. We will use Ember CLI version 1.13.8 and Ember version 2.1.0.

If you just want to play around with the end result, the code is available in this github repository.


I'll assume that you have Ember CLI installed already, so we'll just cut straight to the chase. First, we need to initialize an Ember project with this command:

$ ember new ember-dynamic-table

We will also use ember-cli-mirage in this example. This addon will allow us to easily mock data that will later be displayed in our table. Run this command to install the addon, its dependencies and create a basic configuration:

$ ember install ember-cli-mirage

Next up, we will need to create a model for our data. We will use the resource generator to automatically create the model, route and template files. We will also create a controller:

$ ember g resource users
$ ember g controller users

We create an application adapter:

$ ember g adapter application

And finally, we will add Bootstrap to our project, so that the table looks a bit nicer:

$ bower install --save-dev bootstrap

We need to add bootstrap assets to ember-cli-build.js:

// ember-cli-build.js

module.exports = function(defaults) {  
  var app = new EmberApp(defaults, {

  app.import('bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.eot', {
    destDir: 'fonts'
  app.import('bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.svg', {
    destDir: 'fonts'
  app.import('bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.ttf', {
    destDir: 'fonts'
  app.import('bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff', {
    destDir: 'fonts'
  app.import('bower_components/bootstrap/dist/fonts/glyphicons-halflings-regular.woff2', {
    destDir: 'fonts'

  return app.toTree();

Model and mocking

We will create a simple user model with some basic fields:

// app/models/user.js
import DS from 'ember-data';

export default DS.Model.extend({  
  firstName: DS.attr('string'),
  lastName: DS.attr('string'),
  age: DS.attr('number'),
  createDate: DS.attr('date')

Furthermore, we want to configure ember-cli-mirage to mock some user data. Create a user.js file under the app/mirage/factories folder:

// app/mirage/factories/user.js

export default Mirage.Factory.extend({  
  firstName() { return faker.name.firstName(); },
  lastName() { return faker.name.lastName(); },
  age: faker.list.random(18, 20, 28, 32, 45, 60),
  createDate() { return faker.date.past(); }

The above code defines how to generate sample data using faker.js, so we won't have to worry about populating any models for our development. Now we also need to configure the default mirage scenarios, in order for the addon to actually generate the data:

// app/mirage/scenarios/default.js
export default function( server ) {  
  server.createList('user', 10);

Finally, we need to add a users route to the mirage configuration:

// app/mirage/config.js
export default function() {  
  this.namespace = 'api';


Here we have set the namespace to api. In order for this setting to work properly, we also need to do the same in our application adapter:

// app/adapters/application.js
import DS from 'ember-data';

export default DS.RESTAdapter.extend({  
    namespace: 'api'


Now we need to setup our users route, so that it returns a list of users:

// app/routes/users.js
import Ember from 'ember';

export default Ember.Route.extend({  
  model() {
    return this.store.findAll('user');

And here is the route's template:

// app/templates/users.hbs
<div class="container">  
  <div class="row">
    <div class="col-xs-12">
      {{dynamic-table content=model columns=userColumns}}

As you can see above, we will need to create a dynamic-table component. But before we do that - what is the userColumns object?
Well, before we continue, we have to create a simple configuration object, which we will then pass to our component. This is what it looks like:

// app/controllers/users.js
import Ember from 'ember';

export default Ember.Controller.extend({  
  userColumns: Ember.A([
      'key': 'firstName',
      'displayName': 'First Name'
      'key': 'lastName',
      'displayName': 'Last Name'
      'key': 'age',
      'displayName': 'Age'
      'key': 'createDate',
      'displayName': 'Created at'

They key property will be responsible for getting relevant data out of our model. The displayName will control what's displayed in the table's header.


Finally, we can create the actual component:

$ ember g component dynamic-table

The above command will create the component file along with its template.

Here's the logic:

// app/components/dynamic-table.js
import Ember from 'ember';

export default Ember.Component.extend({  
  sortProps: [],
  sortedContent: Ember.computed.sort('content', 'sortProps'),

  actions: {
    sort(direction, key) {
      this.set('sortProps', [key + ':' + direction]);

Let's stop here for a minute. We want the content of our table to be sorted and in order to do this, we will use the magnificent Ember.computed namespace. It contains a ton of useful methods, one of which is sort, used in our example. Thanks to some Ember magic, our sortedContent will automatically recompute when the model or the sort properties are changed - this will also trigger an update in the template.

We also define a sort action, which will modify the sortProps property depending on the arguments received (they will be sent from the component's template).

Now here's the template:

// app/templates/components/dynamic-table.hbs
<table class='table'>  
      {{#each columns as |column|}}
          <span class='glyphicon glyphicon-triangle-top' aria-hidden='true' {{action 'sort' 'asc' column.key}}></span>
          <span class='glyphicon glyphicon-triangle-bottom' aria-hidden='true' {{action 'sort' 'desc' column.key}}></span>
    {{#each sortedContent as |item|}}
        {{#each columns as |column|}}
            {{get item column.key}}

Here we have defined a simple table. In it's thead we create a row for the columns we've previously defined in the controller. This will render the displayName properties. Next to these names we define clickable arrows (thanks to the Bootstrap Glyphicons), which will trigger the sort action. The actions will pass 2 parameters: the column's key and the direction of the sort, either asc or desc.

Next, we iterate through the model we've passed into our component. For each model we create a new row, where a cell is created for each property we have defined earlier in the controller.

Here we're using a brand new get helper, introduced in Ember version 2.1.0. We pass in the current user we're iterating through and the key we want to display. This will get the value of the property we're interested in.

For example, {{get user 'firstName'}} would display the user's firstName property in our template.

The component in action

Finally, the component should be ready for use. Let's fire up the ember development server:

$ ember serve

Now let's open up our browser and go to the following address: http://localhost:4200/users.

We will see the table component with 10 rows of sample users (generated by ember-cli-mirage).

Click the arrows in the header and - guess what? It sorts! Here's what it looks like:
Creating a Sortable Table Component in Ember.js

Neat, huh?


We have successfully created a dynamic table component in Ember.js. It is easily configurable, accepts any data and has built-in sorting.
All this in only a few lines of code (the component logic itself was 12 lines!). And we didn't have to use any external plugins.

I hope you can see now how easy it is to build semi-advanced functionality in Ember. Much more is possible and quite often we don't need to download any addons.

The code for this post is available at this repository. If you want to see it in action, visit http://kevinkucharczyk.github.io/ember-dynamic-table.

What's next?

The component we've created is pretty basic. If you want to practice some more Ember, here's a couple of things you could do to improve it:

  • Add pagination
  • Add a customizable column width
  • Add lazy loading for further rows of data

I hope you liked what you saw. If you have any questions or suggestions, feel free to comment below!