One of my websites shows tables of data. The data set may change and so i want to provide access to a previous version of the data. My idea is to add a router scope for example
If those are the routes on the page
- /foo
- /bar
i want them also be available as - /v/:version/foo
- /v/:version/bar
That is relatively easy to achieve by just having a v/:version route node
export const ROUTES: Routes = [
// ... common routes here
{
// default application behavior
path: '',
children: routes,
},
{
// versioned scope
path: 'v/:version',
children: routes,
},
]
Now, the inner components use routerLink to link between pages. I want the links to be scoped without implementing a custom routerLink directive. My approach is to override the Router service so that it always produces Url Trees relative to its activated route.
@Injectable()
export class ScopedRouter extends Router {
private scopeRoute = inject(ActivatedRoute)
override createUrlTree(commands: any[], navigationExtras?: UrlCreationOptions): UrlTree {
navigationExtras = navigationExtras || {}
avigationExtras.relativeTo = navigationExtras.relativeTo || this.scopeRoute
return super.createUrlTree(commands, navigationExtras)
}
}
That service is then provided at the versioned route node.
The links are generated as expected. However, navigation does not work because of the following error
core.mjs:10572 ERROR Error: Uncaught (in promise): Error: NG04013: Cannot activate an already activated outlet
Error: NG04013: Cannot activate an already activated outlet
at RouterOutlet.activateWith (router.mjs:2472:19)
at ActivateRoutes.activateRoutes (router.mjs:3037:40)
Besides that, it feels to be a dirty approach. Is there any other technique that can be applied to solve this? Preferably without having to change the implementation of inner components.