Using Ember.js Lesson 2

Welcome to the second lesson on using EmberJS. This will build on from that last Lesson 1, so you will want to check that out if you haven't done so.

Will start with refactoring our client list as a component.

Components

In a nutshell an ember component allows you to define your own application specific HTML tags. A component consists of two parts a javascript file and an accompanying handlebar file. It is isolated by design so its unaware of its surrounding. So any data will have to be explicitly passed into it and any actions must also be explicitly passed out. This encapsulation allows the component to be easily reusable.

Generate a component

To generate a component you will want to run the ember g component command. The component name must include at least one hyphen.

Lets create our component.

$ ember g component clients/client-list

This will generate 3 files.

  • A js file at app/components/clients/clients-list.js
  • A handlebar file at app/templates/components/clients/clients-list.hbs
  • A test file at test/integration/components/clients/clients-list-test.js

Integration Tests

This is the preferred method for testing a component since it allows us to test it in isolation from the rest of the app. Plus this doesn't have the drawback of an acceptance test with having to run the whole app.

Lets write our first integration test. Open test/integration/components/clients/clients-list-test.js and make the following changes.

//test/integration/components/clients/clients-list-test.js
import { moduleForComponent, test } from 'ember-qunit';  
import hbs from 'htmlbars-inline-precompile';  
import startMirage from '../../../helpers/start-mirage';

moduleForComponent('clients/client-list', 'Integration | Component | clients/client list', {  
  integration: true,
  setup() {
    startMirage(this.container);
  }
});

test('it displays the client list', function(assert) {  
  const model = server.createList('client', 3);

  this.set('model', model);
  this.render(hbs`{{clients/client-list model=model}}`);

  assert.equal(this.$('.client').length, 3, "Three clients in list.");
});

Lets break apart the test.

  • We create 3 clients using mirage server.createList('client', 3) like the way we did in the last lessons acceptance test but this time we assigned it to a const called model.
  • this.set('model', model); adds the const model variable to the test context.
  • this.render(hbs`{{clients/client-list clients=model}}`); renders the component to our test context.
  • this.$('.client').length, 3, "Three clients in list."); asserts that our test shows 3 clients.

But before we can run our test we need to add a helper file for mirage. Since an integration test does not load the whole app we will have to manually start Mirage

Create new file at tests/helpers/start-mirage.js

//tests/helpers/start-mirage.js
import mirageInitializer from '../../initializers/ember-cli-mirage';

export default function startMirage(container) {  
  mirageInitializer.initialize(container);
}

In our test file we already import this helper import startMirage from '../../../helpers/start-mirage'; and we start mirage buy calling startMirage in moduleForComponent as

setup() {  
  startMirage(this.container);
}

Now if we run our test.

$ ember test --server

Our test should fail.

Three clients in list.  
Expected: 3  
Result: 0  

Lets fix this by modifying our component template app/templates/components/clients/clients-list.hbs

/*app/templates/components/clients/clients-list.hbs*/
<ul>  
  {{#each model as |client|}}
    <li class="client">{{client.firstName}} {{client.lastName}}</li>
  {{/each}}
</ul>  

Now our test should pass.

Add Component to Template

Last step is to add our new component and make the following changes to app/templates/clients/index.hbs.

/*app/templates/clients/index.hbs*/
{{clients/client-list model=model}}

The next tutorial will look at adding some styling to our site with bootstrap and font-awesome.

You can view the source to the current project on GitHub.

Michael Sparmo

Read more posts by this author.

Lancaster, NY

Subscribe to A developers adventures in WNY

Get the latest posts delivered right to your inbox.

or subscribe via RSS with Feedly!