DEV Community

Cover image for Dynamically set default queryParams in ember > v3.6.x
Michal Bryxí
Michal Bryxí

Posted on

Dynamically set default queryParams in ember > v3.6.x

Imagine you have an app with following route:

https://example.com/calendar
Enter fullscreen mode Exit fullscreen mode

This route can accept optional queryParams from and to that will determine what part of the calendar should be displayed:

https://example.com/calendar?from=2019-09-01&to=2019-09-08
Enter fullscreen mode Exit fullscreen mode

And now imagine that there is a requirement to let the users access the bare URL and display current week.

One option would be to check whether from and to are set, and if not fill those with respective values somewhere inside the code logic.

I am a firm believer of deriving as much state of the app as possible from the URL. So I would suggest: Check whether from and to are set, and if not redirect the app to URL with those queryParams set to respective values. Or in other words: Deriving the state from the outside.

My main reasons on why this is a good idea are:

  • The URL can be bookmarked & shared and every user will see the same data.
  • We have to set the queryParams on one place and every part of the app can to read the values from that place.

I had the redirect approach implemented in my app:

// COMPATIBLE WITH ember v3.4.3

import Route from "@ember/routing/route";
import moment from "moment";

export default Route.extend({
  queryParams: {
    from: { refreshModel: true },
    to: { refreshModel: true },
  },

  beforeModel(transition) {
    let params = transition.queryParams;
    if (!params.from || !params.to) {
      this.replaceWith({
        queryParams: {
          from: moment()
            .startOf("week")
            .format(dateFormat),
          to: moment()
            .endOf("week")
            .format(dateFormat)
        }
      });
    }
  },
});
Enter fullscreen mode Exit fullscreen mode

This stopped working for me while doing an upgrade to ember v3.12.0. Digging through the changelog and pull requests I found out that in ember v3.6.x new RouteInfo objects from and to has been added.

So I made respective changes and now the code looks like:

// COMPATIBLE WITH ember > v3.6.x

import Route from "@ember/routing/route";
import moment from "moment";

export default Route.extend({
  queryParams: {
    from: { refreshModel: true },
    to: { refreshModel: true },
  },

  beforeModel(transition) {
    let params = transition.to.queryParams; // << This line has changed
    if (!params.from || !params.to) {
      this.replaceWith({
        queryParams: {
          from: moment()
            .startOf("week")
            .format(dateFormat),
          to: moment()
            .endOf("week")
            .format(dateFormat)
        }
      });
    }
  },
});
Enter fullscreen mode Exit fullscreen mode

From the wording in the PR I came to a conclusion that I was using a private API of the transition object, which is never a good idea.


Cover photo from Diomari Madulara on unsplash.

Top comments (1)

Collapse
 
kmccullough profile image
Kerry McCullough

Is this still working for you on 3.22? I tried to do this in my own app and when I manually delete the query param from the URL bar and the transition occurs to add the param, an exception occurs.