-
-
Notifications
You must be signed in to change notification settings - Fork 408
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RouteInfo Metadata #398
RouteInfo Metadata #398
Conversation
Co-Authored-By: rwjblue <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Co-Authored-By: chadhietala <[email protected]>
Something we found on our side is that it's very convenient to add and manage static meta data (titles, breadcrumbs titles, tracking info etc.) In the router's route declaration itself, rather than having to look at each indivual routes properties: https://github.com/britishgas-engineering/ember-router-meta |
After our meeting on Friday we decided to move this into final comment period. @Leooo interesting. I think the reason why I opted into putting it directly on the |
Hi! Got a number of questions regarding this.
|
@chadhietala something that the ember-router-meta addon allows is to define most static properties in the router, and override only when needed with some logic in the route, using the related service. We use it to set page names for example - where only a few of them are dynamic. It's pretty much perfect for our use case - it would have been so much a hassle to define page titles etc. in each route, while now we have the best of both worlds and most of the things are defined in the router like for example: this.route('dashboard', {pageName: 'My Account', pageType: 'Account management',
section: 'My Account', path: '/accounts', breadCrumb: 'My account', intent: 'Manage your account'}, function () { Nice job @Mikek2252 btw |
@lolmaus I have intentionally designed the API to dissuade stateful things to occur in the hook and it is meant to be read-only once it is created. This is to align with the other properties on the |
@chadhietala Hmm, so since the data can only be static, the use of this RFC is quite limited? Can it explain what it is intended for and what it isn't? |
|
||
While the `RouteInfo` object is sufficient in providing developers metadata about the `Route` itself, it is not sufficient in layering on application specific metadata about the `Route`. This metadata could be anything from a more domain-specific name for a `Route`, e.g. `profile_page` vs `profile.index`, all the way to providing contextual data when the `Route` was visited. | ||
|
||
This metadata could be used for more pratical things like updating the `document.title`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think document.title
part in the Motivation section is misleading a bit.
While a proposed stateless metadata
design allows you to cover titles for static routes. It doesn't seem possible to support document.title
for routes with dynamic params.
For example, let's say I have a route with a dynamic segment /products/:id
. In this case I would expect to have a product.title
(loaded in the model hook) included to the document.title
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is actually possible with the combination of 2 Router Service. On the Router Service there is currentRoute
which is a RouteInfoWithAttributes
. This has the materialized model on it. So you can do:
export default Route.extend({
buildRouteInfoMetadata() {
return {
title(model) {
return `Product: ${model.name}`;
}
}
}
// ...
});
this.router.on('routeDidUpdate', (transition) => {
document.title = transition.to.title(this.router.currentRoute.attributes);
})
``
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Any time we lean on the global router.currentRoute
in an event handler like this, we are implicitly making timing guarantees about the relative order of events.
Maybe that is OK and unavoidable, but it's worth thinking about alternatives that make the data dependency more explicit:
this.router.on('routeDidUpdate', async (transition) => {
let model = await transition.to.withAttributes();
document.title = transition.to.title(model);
})
(in which I'm imagining a new withAttributes(): Promise<RouteInfoWithAttributes>
method on RouteInfo
.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's a tradeoff here, because the simple thing introduces asynchrony, which then also invites a whole host of other issues.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wait, is there any reason routeDidUpdate
can't receive a transition
that already has RouteInfoWithAttributes
? It seems like by the time we're doing didUpdate we have the info.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes it could receive the RouteInfoWithAttributes
@ro0gr and @lolmaus To deal with shortcomings of not having access to the model data in a natural way we decided to change the type of the object that is passed on the export default Route.extend({
buildRouteInfoMetadata() {
return {
title(model) {
return `Product: ${model.name}`;
}
}
}
// ...
}); this.router.on('routeDidUpdate', transition => {
let model = transition.to.attributes;
document.title = transition.to.metadata.title(model);
}) |
@chadhietala thanks for update. I like I have few more questions. You've provided such an example: document.title = transition.to.title(model); I assume you meant document.title = transition.to.metadata.title(model); or does When I saw your example with a method defined on the buildRouteInfoMetadata() {
return {
['AmIDangerous?']: this.store
}
} Should |
@ro0gr Yes you are correct RE: |
```js | ||
// app/route/profile.js | ||
import Route from '@ember/routing/route'; | ||
import { inject as service } from '@ember/service'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
typo: importing as the name service
but using inject
below
Rendered