Repository navigation
Make resolves/guards injectable/gettable in other resolves/guards on the same level #15032
Copy link
Copy link
Closed
Closed
Copy link
Labels
area: routerfeatureLabel used to distinguish feature request from other issuesLabel used to distinguish feature request from other issues
Milestone
Description
I'm submitting a ... (check one with "x")
[ ] bug report => search github for a similar issue or PR before submitting
[x] feature request
[ ] support request => Please do not submit support request here, instead see https://github.com/angular/angular/blob/master/CONTRIBUTING.md#question
Current behavior
In a resolve, we are able to get the data from resolves on the parents, but not from the same level, so we need to do:
[
{
canActivate: [PlannerForGuard],
canActivateChild: [PlannerForGuard],
children: [
{
canActivateChild: [PlannerForGuard],
children: [
{
canActivate: [RedirectToLastRunGuard],
canActivateChild: [PlannerForGuard],
children: [
{
component: RunsComponent,
path: 'runs/:runId',
resolve: {
deleteRun: DeleteRunResolve,
run: RunResolve
}
},
{
canActivate: [RedirectToLastRunGuard],
component: RunsComponent,
path: 'runs'
}
],
component: SimulationComponent,
path: '',
resolve: {
createRun: CreateRunResolve,
createSimulation: CreateSimulationResolve,
deleteSimulation: DeleteSimulationResolve
}
}
],
path: '',
resolve: {
runs: RunsResolve
}
}
],
path: '',
resolve: {
simulation: SimulationResolve
}
}
]Expected behavior
This could be so much simplified if resolves/guards can 'wait' for other resolves/guards on the same level, like this (it will also make for less guard checks....):
[
{
canActivate: [PlannerForGuard, RedirectToLastRunGuard],
canActivateChild: [PlannerForGuard],
children: [
{
component: RunsComponent,
path: 'runs/:runId',
resolve: {
deleteRun: DeleteRunResolve,
run: RunResolve
}
},
{
canActivate: [RedirectToLastRunGuard],
component: RunsComponent,
path: 'runs'
}
],
component: SimulationComponent,
path: '',
resolve: {
createRun: CreateRunResolve,
createSimulation: CreateSimulationResolve,
deleteSimulation: DeleteSimulationResolve,
runs: RunsResolve,
simulation: SimulationResolve
}
}
]What is the motivation / use case for changing the behavior?
It would allow for less, clearer code + less runs of guards + speed up resolving resolves (as it's now done per level) + no more .parent.parent..... to get the parent resolves (or a custom function to search for a resolve by name ;))
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area: routerfeatureLabel used to distinguish feature request from other issuesLabel used to distinguish feature request from other issues
Activity
dietergeerts commentedon Mar 9, 2017
Ow, I just found out that we can't get resolve data in guards, even from the parents... thats REALLY BAD!
DzmitryShylovich commentedon Mar 13, 2017
@dietergeerts I'm not fully understand your problem. Please add a small plunkr
dietergeerts commentedon Mar 20, 2017
@DzmitryShylovich, what it comes to is the following:
BResolve needs a to process, so inside the resolve function of BResolve, I want to wait for the resolve of AResolve, but right now, we can only get the resolved data from parents. If I'm overlooking the obvious, and BResolve can get the resolved value a, then please tell me how.
DzmitryShylovich commentedon Mar 30, 2017
so you want to access data from
AResolveinsideBResolve, correct? if yes, why wouldn't you combine them into a single resolver? It would simplify things.DzmitryShylovich commentedon Mar 30, 2017
there's another issue #14279 where people want to run resolvers concurrently so we need to make this configurable
dietergeerts commentedon Mar 31, 2017
@DzmitryShylovich , nope, it need to be two resolves, as on other routes, I have them in different levels + they resolve to two separate observables. Putting them together will just end up in code duplication, which is very bad, as you have to make sure you edit it in all places....
I use resolves to construct the app state, where some states depend on others, but the level they are on isn't always known.
kenisteward commentedon May 26, 2017
@dietergeerts I'm at the same brick wall. I actually went as far as to step through all the code for resolvers to make sure i wasn't crazy. What's even more confusing is I figured if I simply made a
this.router.events.subscribe() in the resolver and had it wait for other ones to be done or even looped until it resolved the correct none undefined data that it would work. Sadly that doesn't even work!
dietergeerts commentedon May 29, 2017
@kenisteward , the only way to have them wait for each other is to have component-less, path-less route levels where you can define each level of dependent resolves. BUT it leads to several other issues, like secondary routes that don't work because of the path-less parent, performance impact, as each level is being resolved in series, routerLinks you have to edit each time, as '../' goes up one router config level, and not actually the url, like you would expect.
Imho, the router, though rewritten several times, still isn't designed well for bigger applications... It's even hard to find good examples on how to use resolves in the official docs. It's like they just put it there because ui-router has them... Resolves should be preferred over injecting services into components.
kenisteward commentedon May 29, 2017
@dietergeerts I think it can simply be resolved by adding an order to same level resolves. The router has the context of every resolver in the same level so if it just checks for an order it can allow resolvers on the same level to get each data.
The real issue is for some reason it was made to not add the resolve data until all resolvers finish which makes sense in context just doesn't hit our use case
dietergeerts commentedon May 31, 2017
They should made the all available in the resolves, so you can subscribe to others, even if they are on the same level or not. It should not matter, as it can be that you move one later on, and then you don't want to rewrite resolves that depend on that one.
kenisteward commentedon Jun 5, 2017
@dietergeerts the only reason I disagree with that is the whole mantra of Angular is Unidirectional data. if an earlier resolve could change based off a later resolve that would spell bad news bears for that mantra.
Now as for the same level it would make sense for you to at the very least say make this one run last or something.
dietergeerts commentedon Jun 5, 2017
@kenisteward , well, it's not the actual resolve that will change. I return observables (rxjs) with those resolves, and the result of these observables is part of the application state. But when something happens, for example, the detail view is updated, then the list have to be updated too, so an event is thrown, the list observable picks it up, and the view is updated, no resolves are changing, just the data of the observables that were given by the resolves. I hope this makes sense.
So basically, resolves are there, for me, to build up the application state tree.
Toub commentedon Sep 1, 2017
Here is an API suggestion to address theses issue: #18247 (comment)
trotyl commentedon Jun 9, 2018
Related to #10838
angular-robot commentedon Jun 5, 2021
Just a heads up that we kicked off a community voting process for your feature request. There are 20 days until the voting process ends.
Find more details about Angular's feature request process in our documentation.
angular-robot commentedon Jun 25, 2021
Thank you for submitting your feature request! Looks like during the polling process it didn't collect a sufficient number of votes to move to the next stage.
We want to keep Angular rich and ergonomic and at the same time be mindful about its scope and learning journey. If you think your request could live outside Angular's scope, we'd encourage you to collaborate with the community on publishing it as an open source package.
You can find more details about the feature request process in our documentation.
atscott commentedon Jul 23, 2021
Duplicate of #40577 which is now tracked in #42953
angular-automatic-lock-bot commentedon Aug 23, 2021
This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.
Read more about our automatic conversation locking policy.
This action has been performed automatically by a bot.