Problem
Trying to navigate from http://localhost:4200/#/place/(popup:tabs-modal)
(an outlet) to http://localhost:4200/#/place/someId
Notice that the outlet is basically a child route to "place".
What I can do
I can close the outlet, and just end up on: http://localhost:4200/#/place
: this.router.navigate(['place', { outlets: { popup: null } }]);
Oh then its easy right?
this.router.navigate(['place', 'someId', { outlets: { popup: null } }]);
should then navigate me to http://localhost:4200/#/place/someId
right?
Wrong. The router generates a non-sensical route for me: "/place/(someId//popup:tabs-modal)"
Am I doing something wrong? Or is it just buggy?
this.router.navigate(['/', 'place', { outlets: { popup: null } }]);
You are required to lead from the root path
EDIT:
There is an outstanding issue on angular router hopefully fixed with this pull request: https://github.com/angular/angular/pull/22394
The issue relating to empty router outlets. You also need to know that relative paths are only relative to the router tree (ActiveRoutes) and not the URL. With that in mind, I've created a helper function to get around the issue until its fixed in Angular 6.
import { Router, ActivatedRoute } from '@angular/router';
/**
*
* Angular Relative path tempory solution. Angular doesn't like empty paths.
* Should be fixed in version 6 Pull request 22394
* https://github.com/angular/angular/pull/22394
*
* Angular Issue: https://github.com/angular/angular/issues/13011#issuecomment-274414952
*
* Before removing check relative paths work on named outlet. Using Navigate on named
* outlet currently relates to secondary routes (outlet:'route/test)
* this meant breaking out wasn't possiable using ../../ like documented in
* angular own documentation
*
* key Information: This is relative to routes like anuglar intended NOT URL path
*
* Bug only relates to going to parent and down the tree
*
* @export NavigateByRelative
* @param {string} path
* @param {Router} router
* @param {ActivatedRoute} route
*
*/
export function NavigateByRelative(path: string, router: Router, route: ActivatedRoute) {
/**
* Relative paths should always start with '../' as per angular documentation
* https://angular.io/guide/router#relative-navigation
*/
if (path.startsWith('../')) {
// split path into multiple paths
const paths = path.split('/');
// minus 1 on length as we gurantee need the last index
const totalPathToLastIndex = paths.length - 1;
// current index so we can start at this later on
let currentPathIndex;
// Relative to is so we get to the correct parent
let relativeTo = route;
// Check their is a parent and the current path still intended to go back up the tree
for (currentPathIndex = 0;
currentPathIndex < totalPathToLastIndex
&& relativeTo.parent !== undefined
&& paths[currentPathIndex] === '..';
currentPathIndex++
) {
relativeTo = relativeTo.parent;
}
// Navigate starting at the the currentpathIndex and relative to the current parent
router.navigate([...paths.splice(currentPathIndex )], { relativeTo });
} else {
// else use navigation as normal as this should work correctly
router.navigate([path]);
}
}
Update: 23/10/2018 Sorry for the delay. As of angular 6 the issue with router navigation has now been resolved
Update: 02/04/2019 Angular 7+ has introduce the bug again.