Using Query Parameters in Ember.js

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.

 
Conversation
  • Roger Levy says:

    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?

    • Ivo says:

      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.

      • Ivo says:

        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 };
        }

  • Manoj Mithran says:

    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.

  • Comments are closed.