Skip to content
Aug 21 15

Building the Content Kit Editor

by cory
I published a short article about Content Kit Editor, the project 201 Created has been working on for Bustle this summer, at Medium: Build the Content Kit Editor on ContentEditable.
Aug 7 15

Trying Medium

by cory
I've been trying Medium lately. You can see new posts of mine over there:
Sep 24 14

How Ember.js Components communicate using sendAction

by cory

Components and sendAction

Some people find the use of `sendAction` in Ember components a bit confusing. In this post I'll go over how Ember component use `sendAction` to communicate with controllers and routes, with some examples of common pitfalls.

(P.s. For more info on many other Ember pitfalls see the Emberfest 2014 Presentation by @alexspeller. It inspired me to write this post.)

There are several ways using actions in an Ember component is different than in a route or controller:

1. In an Ember component, unlike an Ember controller or route, you use `sendAction`. (In a route or controller you would just use the `send` method.)

2. In an Ember component, unlike an Ember controller or route, if you call `sendAction` and there is no handler for that action, no error is raised. (In a route or controller Ember would complain with a error message that starts with: "Nothing handled the action:".)

3. The component's `sendAction` is intended to send an action using the component's name for that action. The outer context (controller or route) might have a different name for the same action. The handlebars template is the place to specify the name of the action on the controller/route that will be invoked when the component calls `sendAction` with its name for that action.

Example: {{date-picker}}

As an example, say we have an imaginary {{date-picker}} component. Its semantic name for the action that it sends when a user has selected a date is "pickedDate". The controller context in which this component is being used will have its own name for the action it wants to take when the {{date-picker}} component sends it its "pickedDate" action. In this example, we are using the {{date-picker}} to allow a user to select their birthday, so the action on the controller is "setBirthday". We connect the "pickedDate" component's action to the controller's "setBirthday" action in the template:
{{! index.hbs}}

Pick a date:
{{date-picker pickedDate="setBirthday"}}

Note that the action that the component exposes (`pickedDate`) is on the left side of that assignment, and it is unquoted. The action name on the controller is quoted: it is the literal string value "setBirthday". The way I think of it is that `pickedDate` is a property of the component, and we want to set that component's property to the name of an action on the controller. We have to put quotes around "setBirthday" in the template because we actually do want the `pickedDate` property to equal the literal string "setBirthday". If there were no quotes around "setBirthday", Ember would treat it as a property and replace it with the value of a property named `setBirthday` on the controller, which wouldn't be what we want.

And what does the code inside the component look like, to send this action to its target? Here is a stripped-down example, leaving out the code that the component might use internally to draw a calendar, respond to user clicks/keypresses, etc. We'll assume that that part of the component works and when the user has finished selecting a date the component internally triggers its own action `donePickingDate`. In that case, the code looks like this:
// components/date-picker.js

export default Ember.Component.extend({
  actions: {

    // this is the action that the component handles
    //*internally* when the user has picked the date.
    // The name of this action could be anything that
    // the component author chooses, since it won't
    // be exposed to the outside world.
    donePickingDate: function() {

      // we assume that some other code in the component
      // has correctly set the `theDate` property
      // by this point.
      var theDate = this.get('theDate');

      // Here we communicate to the *outside* of
      // the component, sending our semantically-named
      // "pickedDate" action to the outside world.
      // In index.hbs we had specified that the `pickedDate`
      // property of this component equals "setBirthday".
      this.sendAction('pickedDate', theDate);

It can be complicated to keep the various actions, action names and sendAction calls straight. It begins to get clearer if we start by remembering that a component is intended to be isolated from the rest of our application. It can be easy to forget this because most of the time we use components we are writing them ourselves, but in an ideal world we would have many third-party components that we could drop into our Ember app which we would treat as black boxes.

So, if we consider our component (whether we wrote it our not) to be a black box, we can think of it as having an "action API surface", by which I mean an action or set of actions that it provides to us, the consumers of this component. When using the component, it is our responsibility to specify how our app should respond to each of the action(s) the component exposes. This is what we are doing in our template when we specify `pickedDate="setBirthday"`. We wouldn't want the {{date-picker}} component to need know anything about what we intend to do with the date that the user has selected. It just sends an action that a user picked the date, and the outside context does the right thing with that date. Otherwise we'd need a different version of the component for every context we wanted to use it in ({{date-picker-for-birthday}} that sends 'setBirthday' action, {{date-picker-for-due-date}} that sends 'setDueDate' action, etc.), and we'd lose the reusability that components are designed for.

tl;dr: The component calls `sendAction` with its preferred name for the action, and Ember translates this into the controller's preferred name for the action, which was specified (as a string) in the template.

index.hbs 2014-09-24 15-29-59

The way Ember does this translation internally is when the component calls `this.sendAction('pickedDate', theDate)`, Ember looks up the value of the `pickedDate` property. In this case that value is the literal string "setBirthday". Ember then invokes that action on the controller. Because of the way `sendAction` works, if there is no handler for the "setBirthday" action on the controller or its parent route(s), there will be no error raised and Ember will silently do nothing.

It's worth noting that the action that the component sends is distinct from the properties in its own `actions` hash. It can be confusing because in most cases, the name of the action that the component sends will not be very prominent in the component's own code. It will usually only appear that one time, as a string, in the component's `this.sendAction('pickedDate', ...);` call. The component must rely on the template having set a value for `pickedDate`. Couple this with the fact that `sendAction` will not raise an error, and it's easy get confused when using a component. Consider this template and component:
{{! index.hbs}}

Your birthday?
// component/date-picker.js
  actions: {
    donePickingDate: function(){
      this.sendAction('pickedDate', theDate);

What happens when the user has finished selecting a date? Nothing. No error will be raised. The component will happily send an action named `undefined` (because the value of its `pickedDate` property was never specified in the template), and since there is no handler for an action named `undefined` in the controller or route hierarchy, `sendAction` will silently ignore it and do nothing.

Component Reuse

If you consider using the same component more than once in a template, you can see another reason that it makes sense to specify the controller's action name in the template. For example, say we have a template where a user is trying to pick her birthday *and* set a deadline date for a to-do item:
{{! index.hbs}}

What is your birthday?
{{date-picker pickedDate="setBirthday"}}

When is this to-do due?
{{date-picker pickedDate="setDueDate"}}

In this case, we have two different actions on the controller ("setBirthday" and "setDueDate") that we want to handle the date picker's `pickedDate` action in two different parts of the template. The component code is the same: in both cases, it will just call `this.sendAction('pickedDate', ...)`, and Ember will translate that into the correct action on the controller depending on which part of the template the user was interacting with.

sendAction's default action name: "action"

So far our example using {{date-picker}} has focused on it having a semantically-named "pickedDate" action. Accordingly, we've been having the date-picker component explicitly name that action in its code when we call `this.sendAction('pickedDate', ...)`. However, since many components have a clear single action that they take, Ember provides a convenience by defaulting to sending an action named "action". You could see how this would be convenient if you imagine we are picking components out of a library of potential components. We have {{date-picker}} and {{date-and-time-picker}} and {{time-picker}}. Rather than each of them implementing a different named action ("pickedDate", "pickedDateAndTime", "pickedTime"), the convention is that they will all simply send an action named "action", and so we can specify in our template what action each should take:
{{! index.hbs}}

{{date-picker action="setBirthday"}}

When do you wake up?
{{time-picker action="updateWakeTime"}}

When is this to-do due?
{{date-and-time-picker action="setDueDate"}}

In theory, since "action" is the default action name for `sendAction`, our component code would simply call `this.sendAction(theDate)` without specifying the action name. However, there's an important caveat which is that when you are sending a default action that includes a parameter(s), Ember has no way of telling the difference between this and sending an action by its name. So even if you are sending the default action, if you are including a parameter(s), you must still use "action" as the first parameter: `this.sendAction('action', theDate)`.
Jul 13 14

Physics Simulations with Ember

by cory
I saw this cool javascript simulation of a double pendulum by @MicaelOl on hacker news the other day, and aside from taking me back to my Classical Mechanics class in undergraduate many years ago, it inspired me to try to do the same with Ember and SVG.

As a first stab, I made a single pendulum aka a Harmonic Oscillator:
And then after a little messing around with it (and copy-pasting the equations verbatim from the original javascript sim), I got an Ember double pendulum simulation!
When I was an undergraduate I toiled on a final project related to the Lagrangian for my Classical Mechanics for a couple weeks, and a large part of that was programming a double-pendulum simulation in a java applet. It took me about 2 weeks to make it back then. When I tried to do this in Ember it took me about 1 hour. That's progress.
Jul 10 14

Demystifing Ember Async Testing

by cory
I've been using Promises in my ember code for long enough now that I've started to internalize how they work. So, when I started writing acceptance tests using the ember async test helpers (`visit`, `click`, and so on), I assumed that since those helpers are referred to as "async helpers", they would be promises and I should chain them all together in my test to ensure that the asynchronous activity all happens in the correct order. I understood that ember's testing framework is now promise-aware, and I presumed that meant it would notice when the return value of my test was a promise, and wait for that promise to settle before finishing the test.

I started out writing test code like this:
test('visiting the index page', function(){
  return visit('/').then(function(){
    return click('button#success');
    // all async activity from the IndexRoute and
    // clicking the success button will be finished
    // by now
    equal(currentURL(), '/success');

[Note: This article assumes some familiarity with Javascript Promises. If you're not familiar with them, there are many resources online to learn, including an article I wrote about them that includes an interactive demonstration of promises in action.]

This should look familiar if you're comfortable with promises. Each promise-returning function (`visit`, `click`) is chained via a `.then` call to the next, ensuring that the `visit` promise is settled before we attempt the `click` promise, and so on. Test code like this works just fine, but it is a bit verbose.

Ember's Test Helpers are Fake Synchronous

What I didn't realize originally is that Ember's async test helpers are much smarter than I gave them credit for. In the Test Helpers section of the Ember Guides, this example test code is shown:
test('simple test', function(){
  fillIn("input.title", "My new post");

    equal(find("ul.posts li:last").text(), "My new post");

What! If that code isn't at least lightly blowing your mind, then you either understand Ember's testing helpers better than I did, or you may not be paying close enough attention. I'll illustrate with an example. We want to ensure that the `fillIn` call is not made until the `visit` call has finished (which could take an arbitrary amount of time, due to the fact that it may involve fetching data from an API), and likewise that the `click` call isn't made until the `fillIn` operation has finished. And, finally, any action that Ember takes as a result of clicking "button.submit" (which could involve sending data to an API and/or a route transition) is also finished before the `andThen`'s anonymous function containing our test's assertion is called.

Naive Promise-Returning Test Helpers

Let's take a stab at writing our own pseudo versions of the promise-returning `visit`, `fillIn`, `click, and `andThen` helper functions:
function visit(url){
  return new Ember.RSVP.Promise(function(resolve, reject){
    var timeout = Math.random() * 50; // arbitrary delay{
      // route-visiting code such as `beforeModel` etc
      // would go here
      console.log('Finished visiting ' + url);
    }, timeout);

// assume fillIn, and click are defined similarly

// Now, run these lines:
fillIn("input.title", "My new post");

// Console output:
// (All three statements run at essentially the same time,
//  finishing in a non-deterministic order)
// 'Filled in input.title with My new post' <-- 2nd promise finishes first
// 'Clicked button.submit' <-- 3rd promise finishes before 1st
// 'Finished visiting /posts/new' <-- 1st promise finishes last

Here is a live example showing what happens if we take the naive approach described above. As you can see, just because the `visit`, `fillIn`, and `click` method calls are on subsequent lines, this does not guarantee that their promises resolve in that order. All three helpers start nearly at the same time (you'll see the "1a", "2a", and "3a" log lines appear nearly instantly), but they finish in a random order.
Ember Async Test Helpers Part I

Now it should be somewhat clearer why Ember's test helpers are mysterious. How can Ember ensure that the `fillIn` method call only happens after the `visit` one is done, if we haven't explicitly chained them together? In a normal javascript context, you cannot delay execution of a line based on a previous line. Javascript is non-blocking, so each line executes as soon as the previous one has, even if the previous line has asynchronous behavior that isn't finished yet. This is different from some other languages you probably use. In Ruby, for example, if you had a line that requested data from the database (e.g., `user = User.find(1)`), the execution of the next line of ruby would block waiting until the database had returned its data, and on the next line you could reference the `user` variable, knowing that it had been fully hydrated from the database.

This is not the case for javascript, however, and it is why we used chained promises when we need to guarantee the order of asynchronous method calls. We cannot get away from the need to chain these calls together, but we can get away from explicitly chaining them together, if we are clever.

Context-Aware Test Helpers

Let's redefine our versions of the `visit` and other async helpers. Now, instead of simply returning a promise, they will detect the presence of a global, shared-context promise, and automatically chain themselves to that if it exists. If it doesn't exist, they'll create it and then chain themselves to it. Now our `visit` function, for example, will look like this:
function visit(url){
  // create the shared promise
  // if it doesn't exist
  if (!window.sharedPromise) {
    window.sharedPromise = Ember.RSVP.resolve();

  // chain our code to the shared promise
  window.sharedPromise = window.sharedPromise.then(function(){
    // this is the original `visit` code:
    return new Ember.RSVP.Promise(function(resolve, reject) {
      // ...
      // simulate delay and then call `resolve`
      // ...

Visually, this is what is going to happen now:
Here is a live example showing these global promise-aware pseudo test helpers in action: Ember Async Test Helpers Part II

Putting it all together

As it turns out, this is almost exactly what Ember's testing helpers do! The Ember testing code maintains a shared promise (stored on `Ember.Test.lastPromise`) that it chains each additional async helper call onto. This is the relevant code snippet:

The Ember testing code does a few additional things (such as attempting to resolve nested async promises properly), but at a high level all it is doing is using a shared promise global variable to chain each async helper onto. This is how Ember testing helpers allow you to write code with asynchronous behavior but write it in a synchronous style, without having to explicitly think about promises or promise chains.

At this point you may be wondering how Ember actually knows that the `visit` (or `click`, etc.) async helper has finished all its async behavior. So far we've assumed that the `visit` helper returns a promise that resolves when its async activity is finished, but we've glossed over the actual mechanism by which Ember ensures the promise resolves at the proper moment. The answer to this is that Ember internally uses a heuristic for async activity that involves checking for run loop activity, pending ajax requests, router activity, and more, but that is a subject for a later blog post. Please follow me (@bantic) on Twitter to hear about future posts.


The one takeaway here is that when writing integration tests in Ember, every line of your test should be an async helper or the anonymous function passed to `andThen`. That is, every line of your test should be one of `visit`, `fillIn`, `click`, etc., or an `andThen` call, or inside of the `andThen`'s anonymous function. If you do this, the async-aware nature of Ember's testing code will allow you to write simple, clean tests and be confident that the code will run in the correct order, without having to clutter your test code with explicit asynchronous control flow.

Need Ember.js Testing Help? Hire us!

If your company needs help writing solid tests with Ember, my Ember.js consulting company, 201 Created is available for hire. Please get in touch!