Imagine a service ABService
with a method isAResponsible: () => boolean
and two modules: AModule
and BModule
.
The question is: Is it possible to switch between AModule
and BModule
depending on what isAResponsible
returns? And how do we 'reroute' and rerender if the value of isAResponsible
changes? ABService
may have several dependencies to other services so it would be preferable to make use of the DI system somehow.
Example:
If the route of interest is /aorb
and ABService.isAResponsible
returns true
, than we would like to route AModule
. If ABService.isAResponsible
returns false
however we want BModule
to manage further routing. Note that everything should happen on a shared route.
I tried it with guards and canActivate
/canLoad
but didn't succeed:
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { AorBActivateGuard } from './aorb-activate.guard';
import { ABService } from './ab.service';
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot([
{
path: 'aorb',
canActivate: [AorBActivateGuard],
loadChildren: () => import('./a/a.module').then((m) => m.AModule),
},
{
path: 'aorb',
loadChildren: () => import('./b/b.module').then((m) => m.BModule),
},
]),
],
providers: [AorBActivateGuard, ABService],
declarations: [AppComponent],
bootstrap: [AppComponent],
})
export class AppModule {}
import { Injectable } from '@angular/core';
@Injectable()
export class ABService {
private aIsResponsible = true;
constructor() {}
switch() {
this.aIsResponsible = !this.aIsResponsible;
}
isAResponsible() {
return this.aIsResponsible;
}
}
import { Injectable } from '@angular/core';
import {
CanActivate,
ActivatedRouteSnapshot,
RouterStateSnapshot,
} from '@angular/router';
import { Observable } from 'rxjs';
import { ABService } from './ab.service';
@Injectable()
export class AorBActivateGuard implements CanActivate {
constructor(private abService: ABService) {}
canActivate(
next: ActivatedRouteSnapshot,
state: RouterStateSnapshot
): Observable<boolean> | Promise<boolean> | boolean {
return this.abService.isAResponsible();
}
}
You can you try this instead, I have just checked locally it works, just think it in a different way and you have your solution :)
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { BrowserModule } from '@angular/platform-browser';
import { AppComponent } from './app.component';
import { AorBActivateGuard } from './aorb-activate.guard';
import { ABService } from './ab.service';
@NgModule({
imports: [
BrowserModule,
RouterModule.forRoot([
{
path: 'aorb',
loadChildren: () => {
if ((new ABService()).isAResponsible()){
return import('./a/a.module').then((m) => m.AModule)
} else {
return import('./b/b.module').then((m) => m.BModule)
}
},
},
]),
],
providers: [AorBActivateGuard, ABService],
declarations: [AppComponent],
bootstrap: [AppComponent],
})
export class AppModule {}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With