Skip to content
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

Question: Are lifecycle args a part of the public API of configureRouter? #547

Closed
oneillci opened this issue Oct 27, 2017 · 9 comments
Closed

Comments

@oneillci
Copy link

Are the lifecycle args that are passed to configureRouter alongside the RouterConfiguration and the Router part of the intended public API of configureRouter?

They are currently undocumented.

Currently the configureRouter callback is called like this (in route-loading.js)
return childRouter.configure(c => viewModel.configureRouter(c, childRouter, ...lifecycleArgs)) .then(() => component);

This means I can access any route parameters very easily and conditionally configure my router based on properties of an entity I load. I can also return a Promise. I'm currently doing this, but the docs don't mention any extra parameters (http://aurelia.io/docs/api/router/interface/ConfiguresRouter/method/configureRouter)

I'm worried if I rely on this method it might be deprecated in the future as it's not a documented public feature. Happy to send a pull request to the docs documenting with these extra parameters if that's helpful.

@indfnzo
Copy link

indfnzo commented Nov 26, 2017

Bump, just came across this parameter and would love to know if this is here to stay.

@3cp
Copy link
Member

3cp commented Feb 18, 2018

Well, I am the third.
https://discourse.aurelia.io/t/the-easy-way-to-customize-child-router-based-on-parent-router-param/768?u=huochunpeng

@davismj neither endorses nor totally rejects the usage.

@davismj
Copy link
Member

davismj commented Feb 18, 2018

They are here to stay since we have no intention of introducing breaking changes. I may or may not document them at some point since, as @huochunpeng mentioned, I think this leads developers down a bad path that leads to architectural problems.

@3cp
Copy link
Member

3cp commented Feb 18, 2018

@davismj actually I rely on dynamic behaviour quite a lot. I have many pure backend defined dynamic routes like the one I showed you in the last post of the discourse topic.

In many parts of my app, I have no way to pre-define routes. My app is in cloud business. For instance, I need to show tabs "AWS" and "AZURE" because those are the cloud providers that client (app user) is using. That can be only defined at runtime, because another client might uses "VMWARE" and "ORACLE".

@davismj
Copy link
Member

davismj commented Feb 18, 2018

  1. Create routes for AWS, Azure, VMWare, Oracle
  2. Load user info from database to find out which services are available.
  3. Hide available services in navigation tabs.
  4. Prevent activation of unavailable services.

@3cp
Copy link
Member

3cp commented Feb 18, 2018

You did not get my point. “AWS” is unknown noun in my front-end code, it is just a provider. The list of providers is unknown, and should not be anyway hard coded by frontend code.
The config of any provider is unknown to my front-end, its driven by meta-data provided by backend, then rendered by front-end using exactly same code, same class.

@3cp
Copy link
Member

3cp commented Feb 18, 2018

In our architecture, provider type can be added to the app through plugin (backend). So some client can have their own provider named “Lorem” with a total different config and backend logic.

@fkleuver
Copy link
Member

Keep in mind that configureRouter can actually be called in two different ways:

1. During initial composition (templating lifecycle) of the top-level router-view.

When a router-view is constructed during composition, it calls registerViewPort on the router to register itself as a rendering target. If the router is AppRouter it also calls configureRouter on the component and does not pass lifecycleArgs to it. An important exception.

2. During LoadRouteStep (routing lifecycle) of any child route

When you're navigating to some child route, the normal router pipeline runs and of course you have all the lifecycle args at this point. They are simply based on the url you're navigating to.

Any child route (and associated component) is only composed after you navigate to a url associated with it. Url -> lifecycleArgs, therefore it's only logical to always have those available inside any method of a child routed component.

LifecycleArgs in the constructor?

In fact, there's nothing special about having this during configureRouter. You can even grab them in the constructor with a little detour. Just inject Router as a dependency, which gives you the router of the component above it.

From any Router you can traverse up and down the entire routing/navigation chain and access all lifecycleArgs through currentInstruction and its properties lifecycleArgs, childInstruction, childInstruction.router, etc, even outside of the activation lifecycle.

So in that light I don't see any reason to not "endorse" this as long as its clear the root doesn't get them. But to be fair, the root does have the AppRouter during its composition and that one has - you guessed it - lifecycleArgs :)

It might feel as a semi-private API but aurelia has a not-even-potentially-breaking-change policy anyway, so properties would only be added and never removed.

@3cp
Copy link
Member

3cp commented Feb 19, 2018

Very grateful for your informative inside. I used Router injection but no more than doing manual navigation.

@davismj davismj closed this as completed Mar 21, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

5 participants