6

I got a routing problem in Angular2.

  1. my Module is lazy-loaded (but no problem so far with the basic "loadChildren" approach)
  2. Module itself is being loaded (seen in network-tab of dev-tools)

My Problem:

See my routing code below. The first version is working correctly. The route is found and no errors are thrown when I create a routerLink to .

But, why does my first excerpt work, and second does not??? I don´t want to create a pseudo-path "test" just to get this working. On second example is get this error message.

[...]Cannot match any routes. URL Segment: 'mypath'[...]

Working Routing:

children: export const routes: Routes = [
    {
        path: '',
        component: ParentSplitViewComponent,
        children: [
            {
                path: '',
                redirectTo: 'test'
            },
            {
                path: 'test',
                component: SplitViewComponent,
                children: [
                    {
                        path: '',
                        redirectTo: 'list'
                    },
                    {
                        path: 'list',
                        component: MyListComponent,
                        outlet: 'left'
                    },
                    {
                        path: ':id',
                        component: MyDetailComponent,
                        outlet: 'right'
                    }
                ]
            }
        ]
    }
];

Not working Routing:

children: export const routes: Routes = [
    {
        path: '',
        component: ParentSplitViewComponent,
        children: [
            {
                path: '',
                component: SplitViewComponent,
                children: [
                    {
                        path: '',
                        redirectTo: 'list'
                    },
                    {
                        path: 'list',
                        component: MyListComponent,
                        outlet: 'left'
                    },
                    {
                        path: ':id',
                        component: MyDetailComponent,
                        outlet: 'right'
                    }
                ]
            }
        ]
    }
];

Please don´t rely to naming of files etc. I had to rename paths etc - everything works fine from this point of view. Its just about the routing.

App.routing.ts

{
    path: 'mypath',
    loadChildren: 'app/modules/myModule/my.module#MyModule'
},

Larger excerpt of lazy-loaded-module to understand the structure:

import [...]    


@Component({
    selector: 'parent-split-view-layout-container',
    template: `
    <h1>Parent</h1>

    <router-outlet></router-outlet>
  `
});
export class ParentSplitViewComponent {}



@Component({
    selector: 'split-view-layout-container',
    template: `
    <h1>Vertical Split View</h1>

    <div id="left">
        <router-outlet name="left"></router-outlet>
    </div>

    <div id="right">
        <router-outlet name="right"></router-outlet>
    </div>
  `
});
export class SplitViewComponent {}




/* Routing Definition */
export const routes: Routes = [
    {
        path: '',
        component: ParentSplitViewComponent,
        children: [
            {
                path: '',
                redirectTo: 'test'
            },
            {
                path: 'test',
                component: SplitViewComponent,
                children: [
                    {
                        path: '',
                        redirectTo: 'list'
                    },
                    {
                        path: 'list',
                        component: MyListComponent,
                        outlet: 'left'
                    },
                    {
                        path: ':id',
                        component: MyDetailComponent,
                        outlet: 'right'
                    }
                ]
            }
        ]
    }
];

export const MyRouting: ModuleWithProviders = RouterModule.forChild(routes);

Angular2 Versions:

"@angular/common": "~2.4.5",
"@angular/compiler": "~2.4.5",
"@angular/core": "~2.4.5",
"@angular/forms": "~2.4.5",
"@angular/http": "~2.4.5",
"@angular/material": "^2.0.0-beta.1",
"@angular/platform-browser": "~2.4.5",
"@angular/platform-browser-dynamic": "~2.4.5",
"@angular/router": "~3.4.5",
juli
  • 109
  • 1
  • 9
  • Did you ever solve this? I have something working I'll post as an answer if you still don't have something working. – Kent Bull Jul 07 '17 at 22:47
  • 1
    Should be fixed now! https://github.com/angular/angular/issues/10981#issuecomment-397041242 – maxime1992 Jun 13 '18 at 21:45
  • workaround [stackblitz](https://stackblitz.com/edit/lazy-load-auxilary-workaround?file=app%2Flazy%2Flazy.module.ts) – dasfdsa Oct 15 '18 at 00:03

2 Answers2

4

It's a known bug.
I reported that a month ago https://github.com/angular/angular/issues/13807
It was closed as it's a duplicate of : https://github.com/angular/angular/issues/10981

I needed that too, but as the issue is opened since the 26 of august 2016 and "vsavkin removed their assignment on 16 Nov 2016", I think we'll not see a fix anytime soon.

I ended up with something pretty bad comparing to what I could have done with an auxiliary route but the work gotta keep up. I wish I was able to make a contrib to help on that one but I'm not ...

EDIT: (13/06/18)
Looks like a fix has been merged today!

maxime1992
  • 22,502
  • 10
  • 80
  • 121
  • Thanks, I've spent the past couple of hours trying to work this out. Surprised more people aren't doing this. – Simon Briggs Apr 10 '17 at 08:27
  • 2
    Surprised too ... I had to rethink some part of my app due to this and still not fixed in v4.0.0 ... It's a pity. I'm not even mad because it's open source and I'm not able to fix this on my own but this is a killer feature and lazy loading is also great. Having to choose between both is sad – maxime1992 Apr 10 '17 at 09:43
  • hi @Maxime i am also facing this problem, please help me if you found any solution of it – Muhammad Arslan Jun 16 '17 at 10:15
  • Hi @MuhammadArslan, I've seen your [comment on the Github issue](https://github.com/angular/angular/issues/10981#issuecomment-308997962) but unfortunately, nothing ... It's like nobody's mixing lazy load + aux routes =/ – maxime1992 Jun 16 '17 at 11:53
  • why you called it aux routes? – Muhammad Arslan Jun 16 '17 at 13:24
  • in simple words i think i need children routes within lazy loaded module, but angular does not allow me to do this – Muhammad Arslan Jun 16 '17 at 13:25
  • If you do not have auxiliary routes, it should work just fine. Lazy loading is working great ;) But this has nothing to do with this thread, create a new one with some code and more details ;)! – maxime1992 Jun 16 '17 at 13:56
  • 1
    The bug is finally solved with this Angular release: 11.0.6 (2021-01-06). I am not a 100% sure about the mentioned fix from 2018, but in latest version the problem seems really to be solved - yay. The relevant commits are: router: apply redirects should match named outlets with empty path parents (#40029) (#40315) (f542e4e), closes #38379 #38379 #39952 #10726 #30410 router: Ensure named outlets with empty path parents are recognized (#40029) (#40315) (c722c43) – juli Feb 08 '21 at 15:34
3

I found a workaround here thanks to some helpful folks who ran into the same issue. Your issue is likely that you are trying to use a router outlet as a child on an empty route. I was able to solve a similar issue by naming the route to a static value and making the outlet a child from there.

As others have said, you can track the issue here - https://github.com/angular/angular/issues/10981

Try changing

{
  path: '',
  component: SplitViewComponent,
  children: [
    {
      path: '',
      redirectTo: 'list'
    },
    {
      path: 'list',
      component: MyListComponent,
      outlet: 'left'
    },
    {
      path: ':id',
      component: MyDetailComponent,
      outlet: 'right'
    }
  ]
}

to

{
  path: 'somePath',
  component: SplitViewComponent,
  children: [
    {
      path: '',
      redirectTo: 'list'
    },
    {
      path: 'list',
      component: MyListComponent,
      outlet: 'left'
    },
    {
      path: ':id',
      component: MyDetailComponent,
      outlet: 'right'
    }
  ]
}
Matt Jones
  • 74
  • 3