DEV Community

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

Posted on

1 1

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.

SurveyJS custom survey software

Simplify data collection in your JS app with a fully integrated form management platform. Includes support for custom question types, skip logic, integrated CCS editor, PDF export, real-time analytics & more. Integrates with any backend system, giving you full control over your data and no user limits.

Learn more

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.

SurveyJS custom survey software

JavaScript Form Builder UI Component

Generate dynamic JSON-driven forms directly in your JavaScript app (Angular, React, Vue.js, jQuery) with a fully customizable drag-and-drop form builder. Easily integrate with any backend system and retain full ownership over your data, with no user or form submission limits.

Learn more

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay