angular: Navigating with outlets is confusing: outlets map does not apply to consumed segments

I’m submitting a …

[X] bug report

Current behavior

I have some routes like:

const routes = [
    { path: "", component: HomeComponent, pathMatch: "full" },
    { path: "profile", component: ProfileComponent },
    { path: "menu", component: MenuComponent, outlet: "sidebar" },
];

When the route http://localhost/(sidebar:menu) is open, then I’m able to remove the named outlet and go to http://localhost/ by clicking an anchor like the following:

<a [routerLink]="['', {outlets: {sidebar: null}}]">
    Close
</a>

What doesn’t work is navigating away from the sidebar and also going to another route like http://localhost/profile.

<a [routerLink]="['/profile', {outlets: {sidebar: null}}]">
    Close
</a>

The link that is rendered is http://localhost:3971/profile(sidebar:menu)

Expected behavior

The link that should be rendered is http://localhost:3971/profile.

Repro

https://github.com/tinchou/router-repro

Please tell us about your environment:

Windows 10, Visual Studio 2017

  • Angular version: 2.3.1 (didn’t work with 2.1.0 either)

  • Browser: all

  • Language: TypeScript 2.0.10

About this issue

  • Original URL
  • State: closed
  • Created 8 years ago
  • Reactions: 24
  • Comments: 21 (7 by maintainers)

Commits related to this issue

Most upvoted comments

For what it’s worth, I was able to get this working by using the parent component’s ActivatedRoute instance (this.activatedRoute.parent) in the router.navigate() method. I wrote up my approach here.

Update: Router.navigate doesn’t work either. E.g. the following doesn’t work:

this.router.navigate(["/profile", { outlets: { sidebar: null } }]);

Workaround: add a click handler and call navigate a second time, but only after the first one completes.

this.router.navigate(["/profile"]).then(() =>
            this.router.navigate([".", { outlets: { sidebar: null } }]));

same issue. i have a named outlet call popup, just like in the docs. when i try to close it with: this.router.navigate([{ outlets: {popup: null }}]); It just does nothing.

@WilliamKoza it seems to work using the primary outlet. Now I found it in the docs and it makes sense:

outlet: The name of the RouterOutlet used to render the route. For an unnamed outlet, the outlet name is primary.

This works perfect for me, thanks a lot (but I believe the issue still stands).

Just one gotcha: in my real application it only works if specifying an empty string as the first parameter <a [routerLink]="['', {outlets: {primary: 'profile', sidebar: null}}]">

Came across the same issue I guess… I’m trying to generate this URL: ./Home/(FooOutlet:Foo/(BarOutlet:Bar)).

this.router.navigate(['Home', {outlets: {primary: '', FooOutlet 'Foo', BarOutlet: 'Bar'}}]); equals to /Home/(//FooOutlet:Foo:Foo//BarOutlet:Bar)

this.router.navigate([{ outlets: { 'primary': ['Home'], 'FooOutlet ': ['Foo'], 'BarOutlet': ['Bar'] } }]); equals to /Home(FooOutlet:Foo//BarOutlet:Bar) and an error that it cannot find Bar

this._router.navigate(['Home', { outlets: { home: ['Requests'] } }]).then(() => this._router.navigate([{ outlets: { request: ['EmergencyRequest'] } }])); equals to Home/(FooOutlet:Foo)(BarOutlet:Bar) and an error that it cannot find Bar

Is it me missing something or is Angular unable to construct a URL that goes 2 levels/router-outlets deep?

In the vsavkin’s book, he says :

`We can also remove segments by setting them to ‘null’.

router.navigate([{outlets: {popup: null}}])`

But he never set a path and a outlet. In this case, we can use

<a [routerLink]=“[{outlets: {primary: ‘profile’,sidebar: null}}]”>

If it can help

@bennadel My saviour