Why do I have to make controllers separately?


In the ember-cli you do a ember generate route ‘blah’ to get a route, but nearly always you need a controller so you have to repeat yourself?

Why does ember-cli do this separately? Same thing for this Octane component where it only creates a HBS without the accompanying .js that you almost always need.

Deleting it in the 10% of cases when you don’t need it is a lot easier than having to repeatedly create stuff in the 90% cases where you do.

I think partly the difference is in use case. The main app that I work on, for example, probably has fewer than 30% controllers per route, so generating controllers every time would not be a sensible default in our case. And deleting controllers in the moment isn’t super hard but I think when maintaining an app long term, especially a large one, the less cruft you build up the better. Generating unnecessary files would most certainly result in unnecessary file buildup in some apps I know there have been times where I generated things and then never ended up using them so they just sat there.

I think the case for Glimmer components being template-only by default is even stronger. Template only components render faster, so (I think at least) even by having an empty component js file you could be taking a performance hit. Secondly I think the decision is a gentle push towards really considering if a javascript class is even necessary for your components. Because of the stripped down component API and new features like modifiers there are fewer reasons to need them, so I think it makes a lot of sense to make creating them an extra step.

That said if you really hate creating these things separately you could probably write a couple little scripts and/or custom generators that would create route/controller or template/component pairs for you with a single command.


Thanks for your take on it.

I’d love to know how you are avoiding needing controller JS 70% of the time… I find they are unavoidable. Is it because you are putting components within the template at the top-level?

For instance, if you have a list coming in and you need to filter it in a computed property - I am putting this list as a computed property or tracked property - which needs JS. How do you do this bit or it not something you need in the main app that you work on?

For simple cases like a basic sort we use things like ember-composable-helpers. We also do a lot of things, as you mentioned, in top-level components (including data loading) so routes are typically fairly lean and controllers are pretty often unnecessary. Obviously that’s the only real answer if you have a lot of actions or javascript state to manage.

In my personal projects and other code I’ve worked on I tend to favor data loading in routes a little more and therefore generally use controllers a little more early on. My preference is to start with route and route template (and controller) and then abstract things into components as needed/appropriate. That said between the patterns I use more at my job now and some of the new stuff in Octane I’d probably start leaning more towards components first anyway.

That ember-composable-helpers looks handy. I do like the idea of building blocks to call upon.

I’m surprised that you can’t just tell a router to render a component and make the model automatically pass to it, and perhaps query params could be declared in the router instead.

I did for awhile put in top-level components into the controller, but again I was getting a bit irritated by repeating myself, create controller, create component for the sake of it, put component into controller etc It just adds more infrastructure when it may not be needed.