Imagine you have an app with following route:
https://example.com/calendar
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
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)
}
});
}
},
});
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)
}
});
}
},
});
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)
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.