I'm working on an Angular app where I'm utilizing Angular routing. Below is a snippet from my app-routing.module.ts file:
// app-routing.module.ts:
import {
NgModule
} from '@angular/core';
import {
ActivatedRoute,
Router,
RouterModule,
Routes
} from '@angular/router';
import {
Observable,
Subject,
Subscription
} from 'rxjs';
const routes: Routes = [
// ... adding my routes here.
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {
constructor(
private readonly router: RouterModule,
schoolService: SchoolService
) {
currentSchool$ = schoolService.currentSchool$;
this.addWildCardRoutes();
}
}
The routing works as expected. However, I'm encountering an issue within the addWildCardRoutes() function. In this function, I aim to subscribe to an observable currentSchool$ and dynamically add a wildcard redirect path based on the value of currentSchool, like so:
addWildCardRoutes(): void {
this.currentSchoolSubscription = this.currentSchool$.subscribe(
(currentSchool) => {
if (currentSchool) {
// remove existing wildcard routes:
const index = routes.findIndex((route) => route.path === '**');
if (index !== -1) {
routes.splice(index, 1);
}
// add new wildcard route with current school name:
routes.push({
path: '**',
redirectTo: `${currentSchool.name
.replace(/ /gu, '-')
.toLowerCase()}/home`,
});
} else {
// add a default wildcard if there's no current school
routes.push({
path: '**',
redirectTo: `default/home`,
});
}
console.log(routes); // this console.log() works perfectly
if (this.currentSchoolSubscription) {
this.currentSchoolSubscription.unsubscribe();
}
}
);
}
The problem is that even though the subscription appears to work fine (as evidenced by the console log), the app doesn't recognize the updated routes, and the new wildcards are never added. It seems that the routes must be static and can't be changed after initialization.
How can I dynamically update the routes based on changes in the currentSchool$ observable?
Your code does not work because you only mutate the routes array and the Router does not pick up a new configuration this way.
What you can do is use Router#resetConfig method for updating the router configuration.
Here is your updated method:
Please keep in mind that it does not redirect a user immediately just changes the routes for the next navigation.
Here is a Demo App showing how that could work.
There are quite a few real use cases for doing this. Depending on the use case, it is usually easier to have a Route Guard that can do a redirect based on some data from a service.
It is also not very usual to have such code in a module constructor, a global service or APP_INITIALIZER could be a better choice, depending on the use case.