Readers' Questions: What is the future of controllers? When is it a good time to use them in a modern Ember app?

Welcome to Readers’ Questions, presented by the folks at The Ember Times with a little help from the Ember Core Team and Friends!

Today I’ll be answering this question:

What is the future of controllers? When is it a good time to use them in a modern Ember app?

This question seems to come up frequently! In this article, we’ll cover what controllers are, when you should use them, some historical context, and a investigate how their role could evolve in the future. Special thanks to Edward Faulkner from the Framework Core Team for reviewing and writing a few key sections!

What is a controller?

Behind the scenes, the main job of a controller is to hand data down to other parts of the app and serve as a place to define query parameters. In some ways, you could say that a Controller is like a Component plus a Service. Like a Component, there is a template that can refer to the Controller’s properties and actions. That template is the route’s hbs file. Like a Service, there is only one instance of a given Controller for the lifetime of your application, and anything you set on it will remain set. Also like a Service (and unlike a Component), there are no DOM lifecycle hooks like didInsertElement, and there is no this.element. Every Route in Ember has a matching Controller, whether you generate the file for it or not.

Why are they called Controllers?

At the dawn of Ember, one of the prevailing architectures for web apps was called “MVC”, Model-View-Controller. The model describes the data structure, the view is what the user sees, and the controller is what accepts input and tells the models and views to do things. Years ago, we used to say that Ember was an “MVC front end framework.” However, MVC architecture means a lot of different things to a lot of different people, so we don’t often talk about Ember in MVC terms anymore when teaching new learners. Controllers have mostly the same responsibilities they have always had across Ember’s history, but as the framework developed, the way we think about Controllers changed. The addition of Components shifted our mental models.

When should I use controllers?

In a typical Ember app, a Controller is the only place to define url query parameters. Url query parameters are the part of the url that follows a question mark, like https://emberjs.com?searchTerm=sloths. Query parameters are a way to save information that should survive a page refresh or should be sharable as a bookmark, like a form search term.

Controllers are also often used as a home for actions and properties that could be passed to components. In some ways, you could say that a Controller can do almost everything that the JavaScript file of a component can do. Whether or not you use Controllers for actions and properties is an architectural choice. For example, in my apps, I have a rule that functions that result in a POST, PATCH, or DELETE request to my API should be defined in Controllers. If I need to change something about communications with the server, I always know where to look. There’s nothing that would stop me from letting components handle those types of responsibilities, besides some experiential wisdom :wink: For more information on options for components that handle data, see the past Times Readers’ Question by Edward Faulkner, “Is it bad to load data in components?”

Do I have to use Controllers?

Do you have to? No. Should you? Yes. Using them is considered best practice. If your app has no query parameters, it’s possible that you would never need to write your own code in a controller. However, from an architectural standpoint, you could end up with a mess by avoiding controllers.

For more information on how Controllers help you maintain a neat, predictable data flow, see Jessica Jordan’s past Readers’ Questions answer, What is meant by the term data down, actions up?

What bad things could happen if I don’t use Controllers?

A long time ago, there was a rumor and an article that suggested that Controllers were going away, and that people should strive to not use them, in order to “future proof” their apps. This was bad advice. Unfortunately, a LOT of Ember developers followed it, and those who were not careful ended up with a mess. I inherited such a mess and it took me a long time to dig out of it.

In the best case scenario for avoiding controllers, some people defined a top level component for every route, where they kept actions and properties that would usually go on a controller. This doesn’t really convey any benefits over keeping this information in a Controller. It just gives you another layer of templates to maintain. For developers who didn’t carefully plan this kind of data flow, many ended up with their data handling in scattered components, without rhyme or reason for components that cause API requests versus those that are for display or interactivity.

Are there alternative approaches to Controllers?

Yes, but they are not widely in use. At one point, there was a push to make query parameters available outside of controllers. As a result, some community members developed addons that let developers try it out. For example, check out ember-component-routes.

If you’re feeling adventurous, taking addons for a test drive and sharing feedback to addon creators is a great way to help support the changes you are hoping to see in the framework. However, keep in mind that if apps stay with the safety of the herd and use currently documented best practices, that gives them the easiest future upgrade paths. This is true for any sort of feature that is being explored in Ember. The “play it safe” approach gives you the best change of being able to adopt whatever new thing the community invents with the minimum cost.

What is the future of Controllers?

Ember is community-governed, so you get to help decide the future of controllers! The best way to participate is to write RFCs, write Issues, or comment on those written by others. It would be great to have one less concept to teach new people! However, any successful solution must be a complete one.

An RFC is a “request for comments,” which is the way that Ember considers community and core team proposals. Anyone can write one! If you want to track the status of possible future changes to Ember, read open and merged RFCs. If you are on desktop, this site is a good way to browse merged RFCs. New RFCs are a common topic for the Ember.js Times, which is the weekly blog of the Learning Team, and Ember Weekly, a community-led newsletter.

There are a lot of ideas floating around about how Ember could use (or not use) Controllers in the future, but until an RFC is proposed, discussed, and accepted, there’s not much point in trying to speculate. There are not currently any open/merged RFCs that propose making a change to Controllers. For historical context of past discussions, see this rejected RFC.

Like any feature in Ember, if there were changes made to Controllers, there would also be a well-paved upgrade path, things like codemod tooling, and other forms of support. When the changes would finally land, they wouldn’t be a surprise. A merged RFC is just the green light for future work to be done, not an indication that the feature/change will be added overnight. It’s common for RFCs to be merged and then take a long time to implement. Some of the most successful RFCs have an addon that demonstrates the capability so that people can try it out more quickly. Lastly, Ember has a strong commitment to semver and a careful deprecation process.

In short, don’t worry about it. Use today’s best practices and if you have ideas to share, you can participate in Ember’s RFC process. For questions about how to participate in RFCs, stop by the #dev-ember-learning channel on our Discord server.

Thanks for reading! Please share any other questions you have!

29 Likes

Thank you for this awesome, detailed write-up @jenweber :slight_smile:

2 Likes

Yes!!! Thank you so much, @jenweber ! :slight_smile: I’ve been thinking about that every time I read “ember” and “controller” in the same context ever!!!

2 Likes

I wonder what should be done about this accepted RFC: https://github.com/emberjs/rfcs/blob/master/text/0015-the-road-to-ember-2-0.md

It contains lots of outdated and bad information.

1 Like

I think it’s normal for RFCs to be one outdated over time. I think of them as a catalog of decisions about what features or changes would be accepted, if they came to life. Maybe we should add a note about that to the README.

1 Like

Given the MVVM pattern, one can equate controllers with view models, templates with views; and routes can be used as a standard mechanism to access models, typically from an API.

The view model of MVVM is a value converter, meaning the view model is responsible for exposing (converting) the data objects from the model in such a way that objects are easily managed and presented. In this respect, the view model is more model than view, and handles most if not all of the view’s display logic. The view model may implement a mediator pattern, organizing access to the back-end logic around the set of use cases supported by the view.

1 Like