My app tries to auto-redirect user from '/' to correct other path. To do that we need to make a request for some data and only then decide where to redirect the user. The options are just a few, and the logic to determine the redirect simple.
The problem is that one of the destinations has to request the same data (call the same endpoint). This is because user can go deeper, do something and then go back. Or go 'sideways' and then go back. In other words, return to that route without going via '/'.
My current setup looks roughly as follows
routing
const routes: Routes = [
{
path: '',
component: PagesComponent,
resolve: {
initialDataResolver,
},
children: [
{
path: '',
component: RedirectComponent, // subscribe to route.data and make redirects
},
],
}
...
{
path: '',
component: PagesComponent,
children: [
{
path: UserPath.Root,
// here we have loadChildren and module, but for the sake of brevity I put just the relevant bit as children
children: [
{
path: 'user/organisations',
resolve: {
initialDataResolver,
},
component: UserOrganisationsComponent,
}
],
},
],
},
With this setup, user that goes to '/' experience a call, redirect and then call again. When going straight to /users/organisation, there is just one call (an no redirect, obviously).
So the question is how to skip the second call?
I've tried:
- navigate with state - this was promising but the state is not available in the resolvers
- navigationId - this was also promising, I expected / to have navId==0 and /users/orgs 0 or 1 depending if it was redirected. I was thinking maybe navId > 0 would work. But in reality, the navId was 1 or 2 or sometimes null.
- depending on route data - not available after the redirect (probably scoped in tree)
I went over the router's API and discovered 'lastSuccessfulNavigation' getter. This allowed me to 'peek' at the last nav and check if it was from '/'. This works for my situation because my whole routing is build around the idea that '/' path will redirect user where needed.
So the resolver now looks as follows (the fact it returns true is because our internal reasons. Will also work with regular api calls)