Ember.js — Component and Route Actions

This past weekend I spent an enormous amount of time trying to figure out a solution for a seemingly simple problem. I wanted to find a way to call a router action that has several arguments through a component (that has been rendered in the template/view). — It seems for this problem there was poorly written documentation and virtually no concise information on the interwebs on how to do this correctly — To give a little context, we decided to create an application similar to a CRM but for tracking employment opportunities for users. It’s an easy way for a user to manage all the moving parts of a job search. Every user can create a list of all their job opportunities and add notes, resumes, contacts to that opportunity. Simple.

In our application we inevitably decided to use components for our forms since they were easy to render and could be used multiple times (they’re kinda like partials in ruby). The thing about components is that they are standalone and unaware of the router and the controller. However, once they are called in a template then the relationship is built.

We wrote this form for an opportunity (templates/component/opportunity-form.hbs):

templates/component/opportunity-form.hbs

To grab the values from the component-template form, you need an actual component do this. This is easily done in the component folder (component/opportunity-form):

components/opportunity-form.js

The red box gets the values from the form. We need to do something with those values though. This is where it gets tricky. So, in the blue box the component has a method “sendAction” that is going to trigger an action variable in the rendering of the component in the template along with the necessary parameters for the action(very very confusing because we dont know what action we will be calling….). What parameters though? The action variable corresponds to the addOpportunity action in the route which has an argument of name, position, and description. In our opportunities index is where we render the component. Here is where it finally calls the action and sends the parameters along with it. sendAction(‘action’,…)

template/opportunities.hbs

Now the action that is being called is the addOpportunity action in the route.

router/opportunities.js

If you look closely, addOpportunity needs parameters to be passed in. The component automatically passed those in when we submitted our form. Now, the router can do its thing and create an Opportunity record to our rails api!