Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular2 Routing on lazy-loaded module with multiple named outlets

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",
like image 882
juli Avatar asked Feb 03 '17 10:02

juli


People also ask

Can we have multiple router-outlet in Angular?

You can have multiple router-outlet in same template by configuring your router and providing name to your router-outlet, you can achieve this as follows.

Can I use multiple router outlets in Angular 8?

Yes! We can use multiple router-outlets in same template by configuring our routers and simply add the router-outlet name. You can see in the example.

What is lazy loading in angular2?

Lazy loading modules helps us decrease the startup time. With lazy loading our application does not need to load everything at once, it only needs to load what the user expects to see when the app first loads. Modules that are lazily loaded will only be loaded when the user navigates to their routes.

What is loadChildren in Angular routing?

Use LoadChildren: For lazy loading. Using this property will optimize your application's performance by only loading the nested route subtree when a user navigates to a particular URL that matches the current route path. It helps in keeping the nested routes table separate.


2 Answers

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!

like image 62
maxime1992 Avatar answered Oct 31 '22 01:10

maxime1992


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'
    }
  ]
}
like image 44
Matt Jones Avatar answered Oct 31 '22 01:10

Matt Jones