We all want to make our application as future proof as possible. The result is that in many situations, some of us, avoid using Controllers at any cost. We end up with too much overhead and complexity and it becomes hard to maintain overtime. Here’s an article Dockyard wrote about the Controllers and what they’re good for. I recommend you give it a read if you want to follow some Ember best practices.

Let’s say you want to check if a query param is valid and if it isn’t you want to set it to a default value. Here are 2 simple ways to solve this in Ember.

Validation in the model hook

The only place you have access to the query params from within the route is the model hook. You can access the query param through the params hash.

// app/controllers/booking.js import Controller from '@ember/controller'; import classic from 'ember-classic-decorator'; @classic class BookingController extends Controller { queryParams = ['booking'] booking = null } export default BookingController;

// app/routes/booking.js import Route from '@ember/routing/route'; import classic from 'ember-classic-decorator'; @classic class BookingRoute extends Route { model(params) { if (params.booking) { return this.store.findRecord('booking', params.booking); } this.transitionTo({ queryParams: { booking: 1 } }); } } export default BookingRoute;

Here you check if the query param is present. If the condition is not met then call a transition to the current route with a default query param. And that’s it. Then the new transition is calling the model hook again, loading the model . Because this time the query param is present.

Validation in the setupController hook

You can also add some validation logic into the setupController hook. After all the query params are present on the Controller. You don’t have access to the params hash here but you know that the query params are properties on the Controller.

// app/controllers/booking.js import Controller from '@ember/controller'; import classic from 'ember-classic-decorator'; @classic class BookingController extends Controller { queryParams = ['booking'] booking = null } export default BookingController;

import Route from '@ember/routing/route'; import classic from 'ember-classic-decorator'; import { isEmpty } from '@ember/utils'; @classic class BookingRoute extends Route { model(params) { if (params.booking) { return this.store.findRecord('booking', params.booking); } } setupController(controller, model) { super.setupController(controller, model); let booking = this.get('controller.booking'); if (isEmpty(booking)) { this.transitionTo({ queryParams: { booking: 1 } }); } } } export default BookingRoute;

In the setupController hook, you check if the booking property value is empty. If this condition is true, you’ll transition to the current route with a default query param value. The same we did in the model hook example. Of course you can do any type of validation depending on your app’s logic.

Ember Twiddle working demos

Here are both examples in action. Delete the query param value in the URL and hit enter. You should see it loading the default query param value as expected.

Validation in the model hook

Validation in the setupController hook