Closed Josh68 closed 7 years ago
you might find the injector()
on the transition useful.
resolve: {
something: () => getSomethingPromise(),
somethingElse: (something) => getSomethingElsePromise(something),
somethingElseElse: (somethingElse) => somethingElseElsePromise(somethingElse),
},
redirectTo: trans =>
trans.injector().getAsync('somethingElseElse')
.then(result => return getRedirect(result));
https://ui-router.github.io/docs/latest/interfaces/common.uiinjector.html#getasync
Aha, wish I'd asked this earlier. I will try that out and see if it does what I need. I also wasn't aware you could ladder your resolve
s like that. Thanks for your help.
As it is, I assume there must be a reason that the redirectTo
doesn't automatically wait for all resolve
s to complete before triggering, but I'm not sure.
As it is, I assume there must be a reason that the redirectTo doesn't automatically wait for all resolves to complete before triggering, but I'm not sure.
The idea is that the redirect can happen before any expensive resolves (or resolves that might fail) are fetched.
Consider this example:
.state({
name: 'parent',
resolve: {
spensive: (SpensiveApi) => SpensiveApi.get()
}
})
.state({
name: 'parent.child',
resolve: {
dataForChild: (ChildApi) => ChildApi.failsWhenUnauthenticated()
},
redirectTo: trans => {
let AuthService = trans.injector().get('AuthService');
if (!AuthService.isAuthenticated()) return 'login'
}
})
By processing the redirect first, we avoid making an expensive API call. We also avoid the dataForChild
resolve rejecting (due to HTTP 403, etc) when the user is unauthenticated.
If the resolves must be fetched to process the redirectTo
we can either fetch them inside the redirectTo
hook using the injector()
, or we can declare the resolves as EAGER
. The redirectTo
hook is an onStart()
hook at default priority (0). The EAGER
resolves are also an onStart()
hook, but are high priority (1000).
To specify the parent resolve as eager:
.state({
name: 'parent',
resolve: {
spensive: (SpensiveApi) => SpensiveApi.get()
},
resolvePolicy: {
when: 'EAGER'
}
})
Thanks for the details. I think my design (legacy, on which I'm doing a refactor with ui-router) is just a particular case. I was trying to think top-down with 1.5.x component architecture, and every component from the "master" parent on down depends on data that comes with authentication (it's sort of like a Redux single-store, but that's where the comparison and quality ends).
I did try using the EAGER resolvePolicy, but at least the way I'd architected things at that point in time, it didn't help. I still thing a redirectToPolicy could make sense, but the option to use getAsync in the redirectTo callback, and to inject resolves at that point, should work fine. I'm trying to implement that now and will report back. worked perfectly, so I'm closing this issue.
Not exactly still on topic, but if anyone would like to help contribute to docs with answers provided here in issues, is there a guide for this? Looks like a lot of auto-generated HTML in the meat of the documentation.
Regarding this and another issue, I would suggest putting many concrete examples in your answers somewhere around here:
Interface StateDeclaration ->
Injecting resolves into other things ->
During a transition, Resolve data can be injected into ...
I'd also link from the highest-level tutorial pages. Lots of concrete examples of how to inject resolves into other things, including other resolves and redirectTo methods (sync and async) would be very helpful.
A guide for contributing to docs and website is a great idea!
The short version is:
the website is at https://github.com/ui-router/ui-router.github.io . It is a Jekyll site hosted on github pages.
The API docs are generated using Typedoc from the block comments in the source code.
Thanks. I will give a shot at a PR for something simple. I did fork that repo in order to try to contribute some edits, but wasn't sure how to proceed.
I've added docs for all injectables: https://ui-router.github.io/ng1/docs/latest/modules/injectables.html
Also added a blurb to redirectTo
about getAsync
: https://ui-router.github.io/ng1/docs/latest/interfaces/ng1.ng1statedeclaration.html#redirectto
Thank you for the updates. The API is deep, and I know it's difficult to document everything well.
On Wed, Jan 11, 2017 at 2:26 PM, Chris Thielen notifications@github.com wrote:
I've added docs for all injectables: https://ui-router.github.io/ ng1/docs/latest/modules/injectables.html
Also added a blurb to redirectTo about getAsync: https://ui-router.github.io/ng1/docs/latest/interfaces/ ng1.ng1statedeclaration.html#redirectto
— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/angular-ui/ui-router/issues/3207#issuecomment-272015404, or mute the thread https://github.com/notifications/unsubscribe-auth/AAvFd8YVfqosSfcITOHnffaJ2A2kxGOqks5rRVcFgaJpZM4LOwfE .
I just struggled with doing a redirect after login, and finally realized I couldn't rely on a state's
resolve
s to be satisfied before aredirectTo
hook was triggered. I also played with using a promise in theredirectTo
hook, but this got really messy (and didn't work).I ended up having to use a variation on the "returnTo" resolve pattern from the sample app, but even there, i needed to use a promise with an interval calling a recursive function, waiting for a value from one of the state's other
resolve
s to return (basically, the data for my entire application, which contains the instructions for routing, which are persisted in the db).It seems to me that a state's
redirectTo
should be able to be conditioned to run (or complete) only when all of the current state'sresolve
s have been satisfied. If there's a way to do this already that I'm missing, please give an example. I'm not sure whether there's a way in aredirectTo
of using the injectedtransition
to get a hold of the condition of the state'sresolve
s.Thanks for any feedback, and please close if there is a way of doing this that I'm missing.