5 Ember.js Addons You Should Start Using

ember_Ember-Light
At Atomic Object, we’ve done a lot of work (and a lot of thinking) about the Ember.js application development framework. We also love using open source libraries to help us get more work done, as efficiently as possible. So here are five Ember addons that I think are worth looking into.

1. ember-data-factory-guy

Testing is an essential part of writing quality code. At Atomic Object, we practice Test Driven Development (TDD) whenever possible. Tests often rely on setting up a specific data state within the application, making a programmatic change or calling a function, and asserting that the output or mutated state is correct.

The addon ember-data-factory-guy  is designed specifically for Ember Data models in a testing environment. There are many advantages to using factory-guy instead of filling your tests with repeated @store.createRecord() calls, among them:

  • It helps streamline testing setup.
  • Using factories lets you avoid doing the same thing over and over (creating records manually).
  • The factory-guy syntax is declarative and easy to read.
  • It does a lot of work for you out of the box (provided you are using Ember Data).

Factory-guy comes with generators, so creating a new factory is easy from the command line: ember g factory user will create a factory named users.js in the tests/factory folder. One of the many things I love about factory-guy is that it will automatically fill in hasMany relationships, saving you from the annoyance of creating all the records yourself in test setup.

For instance, a User model may have many cars:

  User = DS.Model.extend({
    name: DS.attr('string'),
    cars: DS.hasMany('car')
  });

The corresponding factory can, by default, fill in a car whenever a user is created, or create custom factories:

FactoryGuy.define('user', {
  default: {
    name: "Jim Bob",
    cars: FactoryGuy.hasMany('car', 1)
  },
  jay_leno: {
    name: "Jay Leno",
    cars: FactoryGuy.hasMany('car', 130)
  }

To create a default user, your test would call FactoryGuy.make('user');. To use our custom jay_leno user, it would be: FactoryGuy.make('jay_leno');. It’s very easy.

Obviously, that only scratches the surface of the features factory-guy provides. You can check out more at factory-guy’s github repository.

2. ember-ajax

Most ambitious web applications are backed by some web server that provides an API consumed by the web app. Libraries like Ember Data will automatically make requests to the API, but often developers will need to make requests themselves. In those cases, you should reach for the ember-ajax addon.

Ember-ajax provides a straightforward AJAX service for use in Ember applications (unsurprisingly, it wraps jQuery AJAX). It provides convenient HTTP verbs: POST, PUT, DEL, PATCH–but not GET (get is a special method reserver on every Ember.Object). Since this addon is a service, it can be included in your Ember code via dependency injection:

import Ember from 'ember';

export default Ember.Route.extend({
  ajax: Ember.inject.service(),
  model() {
    return this.get('ajax').request('/posts');
  }
});

And since it’s a regular Ember.Service, it can be easily injected into tests and mocked, stubbed, etc.

3. ember-wormhole

There are times when you may come across a case where a UI is a logical child of another UI element, but it needs to render as a top-level DOM element. In these cases, look no further than ember-wormhole, which allows you to render a block anywhere on the page.

My colleague Jeanette Head correctly pointed out that rendering to arbitrary DOM locations can be a bad smell in a web application, and this addon provides plenty of rope for a developer to get themselves into trouble. I personally have come across two clear and common cases where the wormhole has been useful:

  • Modals: Say you have a component deeply nested in an application, and it needs to open a modal which pops up and covers the entire UI or grays out the rest of the screen–but it uses data that is in the scope of the component. In this case, the wormhole would lead from the component to some top-level DOM element where the modal resides.
  • Popovers: When validating an input field or providing a small contexture UI, we may want to display an element that sits “on top” of the field or control. In this case, I have struggled with containing div elements that have CSS overflow properties and incorrectly clip the popover. Ember-wormhole can be used to bring the popover up to a higher level in the DOM and avoid the overflow clipping problem.

Ember-wormhole is very powerful–and can be very useful–but always remember, with great power comes great responsibility.

4. ember-truth-helpers

It can be annoying to create computed properties on Ember Components and Controllers just to perform simple logical operations. In the past, I have found myself tediously wiring up simple computed properties using Ember.Computed not, equal, gte, lte, etc. A little addon called ember-truth-helpers has helped me avoid writing all these extra computed properties myself. It lets you move the logic into the template, using a nice syntax:

truth-helpers

5. ember-i18n

Finally, a favorite and (in my opinion) a necessity for developing any Ember application that requires localization: ember-i18n.

To declare translations, files must go in app/locales/[locale]/translations.js, and export an object containing functions or strings as keys that will be used to translate for a given locale. For instance, this translations object will have a key user.edit.title that will translate to “Edit User” in English:

export default {
  'user.edit.title': 'Edit User'
}

Any text that must be translated will use that above key to render the correct translated content. Ember-i18n provides handlebars helpers and an i18n service for translating: the handlebars {{t}} helper.

{{t "user.edit.title"}}

The above code will render Edit User on the page. The service provides a t function used to translate as follows:

export default Ember.Object.extend({
  i18n: Ember.inject.service(),

  afterModel: function(post) {
    document.title = this.get('i18n').t('title.post', { post: post });
  }
});

Ember-i18n has a lot of other cool features including location fallback, nested translations, string interpolation, dynamic locale setting, pluralization, etc. It also has great documentation. Be sure to check it out at its github repo.

I’ve covered five Ember addons that I’ve found to be extremely useful, but I always love to hear about new ones that I haven’t tried. What addons have you used in your Ember projects?

Conversation
  • Damien White says:

    Ember-data-factory-guy is absolutely awesome, it’s definitely #1 in my book. I use it in every project I work on and it just keeps getting better and better. Dan Sudol (the author) has done an amazing job with the tool. If you’re using Ember-Data, ember-data-factory-guy is THE tool for testing. Nothing is easier to use.

    Anyway, great list. There are so many wonderful Addons out there. Ember is just awesome.

  • I think ember-concurrency is the best new addon of 2016. It solves so many problems with asynchronous tasks.

    • Troy says:

      This. Man is that amazing. Watch the video of him demoing it at embercon if you haven’t yet.

  • Matthew Marcum says:

    https://github.com/tomdale/ember-network instead of ember-ajax. Get ready for fast-boot!

  • Hao says:

    No way. You can’t be more helpful.

  • Ken says:

    Seems like there is a lot of overlap between factory-guy versus mirage or do you see them as serving distinct use-cases?

    • John Fisher John says:

      It looks similar, but I haven’t used Mirage.

      One thing factory-guy will do (and maybe Mirage does, too) is populate Ember Data belongsTo and hasMany relationships. In our app this is very handy because it will go ‘up’ and ‘down’ our hierarchy of objects and fill everything in that is required (e.g., for validations). FG has helpers like FactoryGuy.belongsTo and FactoryGuy.hasMany.

      • Ken says:

        Yes Mirage does this and has support for serializers too. If you do end up taking a look at mirage — it’s an amazing addon — I’d be interested in how you’d compare them. Either way, thanks for making me aware of factory-guy.

  • Floby says:

    this is an awesome list. Thank you. However I have some reserves about #4 truth-helpers.

    In my opinion, the choice of ember to enforce strict property binding for conditionals is a good thing because it encourage to test your predicates with unit tests and to name your conditions which is also a Clean Code recommendation. truth-helpers allow you to create complex conditionals with no rule on naming or order which in turn can create code that is hard to maintain.

    For my teams, I’d rather stick with the usual One-Tested-Property-As-Named-Condition

    • John Fisher John says:

      It’s a fair point. I agree that care must be taken when using those truth-helpers- they can lead to a slippery slope of spaghetti logic in the template (one reason I like Ember is its conventions keep JS logic is kept out of the templates).

      On the other hand, it can be annoying to wire up a lot of Ember.computed.not/and/or/equals helpers when a simple conditional in the template would do the trick.

  • Comments are closed.