Article summary
Many web applications use query parameters in one way or another. Query params are great for defining things that don’t make sense as a dynamic segment in the URL. Ember realizes the importance of query params, and it has built a great way to interface with them.
There are three places where you may need to use query parameters in your Ember application: routes, controllers, and templates.
Routes
Sometimes you’ll want to use query parameters to retrieve data from a server. Routes are a great place to do this because the route hooks (beforeModel
, model
, and afterModel
) wait for promises to resolve before initializing the controller.
You can specify a queryParams
object on the Route. By default, changes to query parameters in a controller will not refresh the model. This becomes a problem when those query parameters are used to make a request to the server or to help define the controller’s model. However, in the route you can tell Ember to refresh the model whenever a query parameter changes.
By default, controllers use pushState
to update the URL whenever a query parameter changes. Using pushState
will add an entry to your browser’s history. If you don’t want your browser to see every query parameter change as a new entry, you can add a property in the route to tell Ember to use replaceState
instead of pushState
.
AnimalsRoute = Ember.Route.extend
queryParams:
phylum:
refreshModel: true # Refresh the model whenever phylum changes
replace: true # Do not add an entry to the browser's history when phylum changes
as: 'animalPhylum' # Alias the phylum query parameter to animalPhylum
model: ->
@store.findAll('animals', phylum: @get('animalPhylum'))
Controllers
Query parameters are also available for use in controllers. Controllers may want query parameters for a variety of reasons, like passing them to the server or showing a tutorial dialog when a user first visits a page.
Controllers also contain a queryParam
parameter. The parameter can be set to an array of strings that represent the query parameters, or it can be set to an object where the key is the query parameter in the URL and the value is a string that generates a property available within the controller.
AnimalsController = Ember.Controller.extend
# Option 1, as an array
queryParams: ['domain', 'kingdom', 'phylum', 'firstVisit']
# Option 2, as an object
queryParams:
domain: "animalDomain"
showVisitModal: Em.computed.oneWay "firstVisit"
Templates
Query parameters can also be helpful in templates. Specifically, you may want to use query parameters for links that point to another route in your application. Luckily, the link-to
helper has a query-params
subexpression helper. You can pass both hardcoded and bound values to the query-param
helper.
{{link-to "animals" "Nematodes" (query-params phylum="nematodes")}}
Wherever you decide you need query parameters in your Ember application, there is a well defined interface for them. For further reading, check out the Ember documentation on query parameters.
Hi,
Can you help me?
How do you transform for instance dates from the query parameters into date objects before then get stored in the route’s controller and children components?
Hi Roger,
Funny that we’re both trying to do similar things around the same time.
Hopefully I’m understanding your question, if not let me know. I’m using Ember 1.13 so things may have changed since then, but I figured I’d let you know how I’m doing it in case it’s helpful for you.
Say you accept a query param on a “calendar” route like so:
example.com/calendar?date=2016-08-04
then in the model() hook of the calendar route you can transform the param into a Date object and pass it to the setupController() hook:
model(params) {
let dateObj = new Date(params.date);
// do whatever else you need to in the model and include the dateObj in the returned object
// then for example do
return { dateObj: dateObj };
}
setupController(controller, model) {
this.controller.set(‘attrs.date’, model.dateObj);
}
Then you can pass it to the children components.
I see none of my indentation went through. Here’s a rework of the model hook that might be more readable (can’t edit my reply).
model(params) {
let dateObj = new Date(params.date);
// Do whatever else you need to in the
// model and include the dateObj
// in the returned object/
// Then for example do
return { dateObj: dateObj };
}
Hi,
Can you help me on filterby in ember?
I want to filter the controller by year.Ex. I want to get records for year 2015,2017.