1

I'm loading a module with data from the resolver. The loaded module has the usual empty-path redirect to the first child route. But I want to redirect to a specific route based on the resolved data.

In the current example I have a child module with three components. The Resolver in the root module provides the data to which component should be redirected to.

AppModule:

const routes = [
  {
    path: '',
    redirectTo: 'steps',
    pathMatch: 'full'
  },  {
    path: 'steps',
    loadChildren: './steps/steps.module#StepsModule',
    resolve: {
      step: StepResolver,
    }
  },
]

@NgModule({
  imports:      [ BrowserModule, RouterModule.forRoot(routes) ],
  declarations: [ AppComponent ],
  bootstrap:    [ AppComponent ]
})
export class AppModule { }

ChildModule:

const routes = [
  {
    path: '',
    redirectTo: 'step1', // <-- this has to be dynamic based on the provided data
    pathMatch: 'full'
  },  {
    path: 'step1',
    component: Step1Component
  },  {
    path: 'step2',
    component: Step2Component
  }, {
    path: 'step3',
    component: Step3Component
  },
]

@NgModule({
  imports:      [ CommonModule, RouterModule.forChild(routes) ],
  declarations: [ Step1Component, Step2Component, Step3Component ],
})
export class StepsModule { }

The Resolver returns the step that should be redirected to

@Injectable({
  providedIn: 'root'
})
export class StepResolver implements Resolve<string> {
  resolve(route: ActivatedRouteSnapshot): Observable<string> {
    return of('step2');
  }
}

How can I redirect to the route based on the provided data? Are there any routing hooks that I can use?

Throughts:

  • CanActivate on the empty child path -> CanActivate is called after provide, so: no data
  • load an empty component in empty child path and trigger the redirect at OnInit -> a bit smelly for me
Benjamin Ifland
  • 137
  • 1
  • 10
  • 1
    So your resolver either returns `step1`, `step2` or `step3`? How does it determine what step to return? – Tom Aug 12 '19 at 08:36
  • Its only a stub. In my real app I load data from a server and determine the step from that. – Benjamin Ifland Aug 12 '19 at 08:38
  • There will always be a string containing the next step? It would be helpful if you could provide the actual code for the resolver. – Tom Aug 12 '19 at 08:40
  • The business logic for mapping the resolved data to the redirect route is not the issue. The Question is, where I have to place the commands for the routing. And this place should have access to the provided data. – Benjamin Ifland Aug 12 '19 at 08:45

1 Answers1

0

You could evaluate what next step is necessary and then navigate to the the specific route:

this.route.navigate([yourStep]);

You would have to import Router:

constructor(private route: Router) { }

Edit:
Create a service with something like this:

goToStep(step: string) {
  this.route.navigate([step]);
}

And the resolver considering the code you provided:

resolve(route: ActivatedRouteSnapshot): Observable<string> {
   return this.stepService.goToStep('step2');
}
Tom
  • 3,672
  • 6
  • 20
  • 52
  • to the Edit: Hm, could work but is imho not a good solution. Regarding the SRP the only task of a provider is to provide data. A guard would be the best way, because by design it can return an UrlTree - but the resolcver is the lase called routing Hook. Perhaps I write a service, subscribe the RoutingEnd and redirect then. – Benjamin Ifland Aug 12 '19 at 09:31