I’ve taken a break from Ember for over a year while I focused on React, Meteor, and Backbone for personal and professional projects. While I wasn’t looking, Ember has transitioned to a new version, fully embraced its Glimmer rendering engine, and restructured the internal router. EmberJS describes itself as “a framework for creating ambitious web applications,” and that’s why I returned to it when I was tasked with transitioning our app from Backbone to a new framework. Because what’s more ambitious than completely rewriting your app?
The structure of the application primarily consists of a series of nested models. The user will select an event, which will load event model from the API. From this page, the user can view the categories for the event, which pulls in a list of categories. The number of categories here can vary from 1 to 150 depending on availability. From here, they can view an individual category, then a ticket for that category before adding to a cart and checking out. The tree for the app looks like this:
Router + Data
So I wanted to get the query param on a nested route in my Ember app, and I could not figure it out. I’ve had issues working with nested routes when working with Ember-Data, so I knew the solution was going to be more complicated than not.
The ticket can change based on availability, so it isn’t guaranteed to be the same for each request. Therefore, I am doing a separate call for the ticket on the route. In the setupController for the route, I’m able to join the category model and ticket model as a single output to the template. The category data doesn’t change from the initial fetch, so I can just call Ember-Data’s store, then perform a query for the ticket data. It’s really handy, and the template won’t render until both promises are fulfilled.
Of course, now I need to complicated it even more. I need to pass a query parameter to the ticket API call with the number of tickets needed to display. The goal is to show a sold-out message if there are not enough tickets available for an order.
I could add a query parameter to indicate the number of tickets needed. Accessing query parameters are not the easiest thing to do in Ember routes. I would need to dig into the router state to access it:
this.router.currentState.routerJsState.queryParams That seems pretty smelly.
But then, why even have a query param? What it it’s use beyond the api request? Like all other things in Ember, a query string is really just a property, so I can place that property anywhere accessible to the router. Enter services.