New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Lazy loaded module in named outlet throws error #12842

Open
molcik opened this Issue Nov 13, 2016 · 35 comments

Comments

Projects
None yet
@molcik

molcik commented Nov 13, 2016

[x] bug report
[ ] feature request
[ ] support request

Current behavior
Navigating to route with lazy loaded module in named outlet throws error:

Uncaught (in promise): TypeError: Cannot read property 'routes' of undefined

Expected behavior
Navigating to route with lazy loaded module in named outlet without errors.

Minimal reproduction of the problem with instructions
When I have configured my routes with named outlet and want to have lazy loaded module in that outlet.

export const routes: Routes = [
 {  
   path: '',
   component: AppComponent,
   children: [
     {
       path: '',
       loadChildren: "app/home/home.module#HomeModule"
     },   {
       path: '',
       loadChildren: "app/about/about.module#AboutModule",
       outlet: "about"
     }
   ]
  }
];

Here is the plnkr to demonstrate the behavior: http://plnkr.co/edit/nK9kJYdakXILZU0UKFrP?p=preview
(Anything is displayed because of error)

What is the motivation / use case for changing the behavior?
Using lazy loaded modules in named outlets.

Please tell us about your environment:

Angular version: 2.0.X

Browser: [all | Chrome XX | Firefox XX | IE XX | Safari XX | Mobile Chrome XX | Android X.X Web Browser | iOS XX Safari | iOS XX UIWebView | iOS XX WKWebView ]

Language: [all | TypeScript X.X | ES6/7 | ES5]

Node (for AoT issues): node --version =

@CalvinDale

This comment has been minimized.

CalvinDale commented Dec 1, 2016

This issue also affects updating matrix-params via router.navigate(). E.g.,

  {
    path: '', component: DummyWrapperComponent, // Wrapped because a component-less route cannot have a named outlet
    outlet: 'popup', // Targetting `popup` outlet in wrapper's parent
    children: [
      {
        path: 'state-scratchpad',
        // outlet: 'popup', // Can't target non-primary outlet for lazy-loaded component
        // params: { tcomp: '', tmake: '' }, // These matrix params can be updated via router.navigate() if targeting
        //     `primary` outlet without the wrapper; but for `popup` outlet the wrapper is required
        loadChildren: 'app/state-scratchpad/state-scratchpad.module#StateScratchpadModule'
      }
    ]
  }
@pleerock

This comment has been minimized.

pleerock commented Jan 6, 2017

have anyone find a temporary workaround for this issue? (goal is to load component in named outlets lazily).

@UnwrittenFun

This comment has been minimized.

UnwrittenFun commented Jan 6, 2017

We have this

    {
        path: 'me',
        outlet: 'hub',
        component: ProxyRouteComponent,
        children: [
            {
                path: '',
                loadChildren: 'hub#HubModule',
            },
        ],
    },

Where proxy route component is simply

import { Component } from '@angular/core';

@Component({
    selector: 'b-proxy-route',
    template: '<router-outlet></router-outlet>',
})
export class ProxyRouteComponent {
}
@pleerock

This comment has been minimized.

pleerock commented Jan 6, 2017

@UnwrittenFun yeah it works however it brings a side effect - extra level in the component tree which can bring some problems in some use cases

@RatkoR

This comment has been minimized.

RatkoR commented Jan 22, 2017

I know It's been a while since commit 8f2fa0f, but can you @vsavkin remember why you added that "a componentless route cannot have a named outlet set" guard.

Is it because it's just not possible to lazy load in such a way (because maybe router is designed so) or is this something that will eventually be resolved sometime.

@Gromov-Roman

This comment has been minimized.

Gromov-Roman commented Mar 21, 2017

@UnwrittenFun not work for me on angular 4 rc.5. Have any idea?

@kenese

This comment has been minimized.

kenese commented Mar 26, 2017

Hi there, I am also interested to know if we will be able to lazy load secondary routes in the future

@martzcodes

This comment has been minimized.

martzcodes commented Apr 4, 2017

@vsavkin @jeffbcross We ran into this in your ng-conf session

hajjem-ayoub added a commit to hajjem-ayoub/angular that referenced this issue May 16, 2017

fix(router): Named route and lazyloading
a small patch to be able to lazyload a module in a named router-outlet with one restriction is to specify the lazyloaded named outlet first in the routing.

angular#12842

@hajjem-ayoub hajjem-ayoub referenced this issue May 16, 2017

Closed

fix(router): Named route and lazyloading #16812

1 of 3 tasks complete

hajjem-ayoub added a commit to hajjem-ayoub/angular that referenced this issue May 16, 2017

fix(router): Named route and lazyloading
a small patch to be able to lazyload a module in a named router-outlet with one restriction is to specify the lazyloaded named outlet first in the routing.

angular#12842

hajjem-ayoub added a commit to hajjem-ayoub/angular that referenced this issue May 16, 2017

fix(router): Named route and lazyloading
a small patch to be able to lazyload a module in a named router-outlet with one restriction is to specify the lazyloaded named outlet first in the routing.

angular#12842
@aherrick

This comment has been minimized.

aherrick commented May 19, 2017

We are seeing this as well. We are simply trying to lazy load a module and have multiple named router outlets.

@jotatoledo

This comment has been minimized.

jotatoledo commented Jun 27, 2017

Same issue here, I want to lazy load a module with a path to a named outlet. Cant figure a way to get it to work

@hajjem-ayoub

This comment has been minimized.

hajjem-ayoub commented Jun 28, 2017

Is there any information about this issue?? just so I know in my company if we should do a temporary solution until it's fixed or think about a more permanent solution. I just need an answer to a simple question:
"is this planned in the @angular/router team roadmap or not for now??"

@rsach

This comment has been minimized.

rsach commented Jun 29, 2017

i'm facing the similar issue , is there any work around for this?

@karsunke

This comment has been minimized.

karsunke commented Jul 6, 2017

The workaround of @UnwrittenFun works for me in 4.2.5 (maybe in every version). Thanks alot.

jasonaden added a commit to jasonaden/angular that referenced this issue Jul 14, 2017

fix(router): Named route and lazyloading
a small patch to be able to lazyload a module in a named router-outlet with one restriction is to specify the lazyloaded named outlet first in the routing.

angular#12842

jasonaden added a commit that referenced this issue Jul 14, 2017

fix(router): Named route and lazyloading
a small patch to be able to lazyload a module in a named router-outlet with one restriction is to specify the lazyloaded named outlet first in the routing.

#12842
@wosevision

This comment has been minimized.

wosevision commented Jul 24, 2017

+1, trying to lazy-load a couple of heavier views in my sidebar. Seems a pretty reasonable use-case.. I'd be interested to hear if there's an actual technical difficulty in implementing this, because what I'm seeing here is a couple of easy workarounds and an error message that feels more like an oversight than intentional – the error that's thrown doesn't mention loadChildren and only checks whether there's a component attached to a named outlet.

mhevery added a commit to hajjem-ayoub/angular that referenced this issue Jul 26, 2017

fix(router): Named route and lazyloading
a small patch to be able to lazyload a module in a named router-outlet with one restriction is to specify the lazyloaded named outlet first in the routing.

angular#12842
@mchavaillaz

This comment has been minimized.

mchavaillaz commented Jul 30, 2017

I tried the workaround of @UnwrittenFun with the version 4.2.5 but it doesn't work.

Could somebody help me with the workaround? @karsunke ?

My test application is available in this repo --> https://github.com/mchavaillaz/angular-router-named-outlet-lazy-loaded

I have the erro message "Error: Cannot match any routes. URL Segment: 'module-one'"

@karsunke

This comment has been minimized.

karsunke commented Jul 31, 2017

@mchavaillaz I created an issue in your repository, where we can discuss a solution: mchavaillaz/angular-router-named-outlet-lazy-loaded#1

@mchavaillaz

This comment has been minimized.

mchavaillaz commented Aug 1, 2017

Ok I resolved my problem. A full example of module lazy loaded displayed in a named router outlet is available here --> https://github.com/mchavaillaz/angular-router-named-outlet-lazy-loaded.

@George02

This comment has been minimized.

George02 commented Aug 26, 2017

Any update on this ?

3 similar comments
@topikus

This comment has been minimized.

topikus commented Aug 29, 2017

Any update on this ?

@Jinkwon

This comment has been minimized.

Jinkwon commented Sep 4, 2017

Any update on this ?

@rBull

This comment has been minimized.

rBull commented Sep 14, 2017

Any update on this ?

@gmanio

This comment has been minimized.

gmanio commented Sep 24, 2017

Any update on this?

@infinite2009

This comment has been minimized.

infinite2009 commented Oct 3, 2017

There seems to be no update. I get stuck in this.

@clarkmclean

This comment has been minimized.

clarkmclean commented Oct 19, 2017

Any update on this?

@som30ind

This comment has been minimized.

som30ind commented Oct 23, 2017

I am facing same issue with unnamed router-outlet with Lazy Loaded Module. It throws same error

Uncaught (in promise): TypeError: Cannot read property 'routes' of undefined

Any fix for this?

@erbsenkoenig

This comment has been minimized.

erbsenkoenig commented Oct 23, 2017

@wosevision

This comment has been minimized.

wosevision commented Oct 26, 2017

Though I don't want to speak on behalf of the Angular team, I feel like something needs to be said here:

This issue doesn't get closer to resolution in proportion to the number of comments that say "Any update on this"/"Any fix for this"/etc. Thumbs-upping those comments doesn't magically go into some petition for the Angular team to finish this.

If you're stuck, read the thread – there's a workaround, which as the name suggests, will get you working. If you'd like to get updates on this, save some keystrokes by clicking the 'Subscribe' button – that allows you to receive updates in your email. You'll also receive updates every time someone comments "Any update on this?", so please, don't be that person.

Better yet, be the change you want to see in the world and submit a pull request.

@gmfun

This comment has been minimized.

gmfun commented Nov 30, 2017

Solution proposed by @UnwrittenFun mostly works, but on refreshing the page with secondary route this throwing error
Cannot read property 'routes' of undefined
I have tried remove lazy loading
{ path: "test", component: ModalComponent, outlet: 'modal'},

This is happening if I have a route with path: "" somewhere in app routing, Works fine if I change this to path: "something"

@mir4ef

This comment has been minimized.

mir4ef commented Nov 30, 2017

I think the error cannot read property 'routes' of undefined is for the primary outlet. I had the same issue on refresh, so I had to specify a route for the primary outlet as well:

this.router.navigate([{ outlets: { primary: [ 'home' ], modal: [ 'login' ] } }], { skipLocationChange: true });

doing

this.router.navigate([ '/home', { outlets: { modal: [ 'login' ] } }], { skipLocationChange: true });

didn't throw the error, but it didn't populate the named router outlet

@ngbot ngbot bot added this to the Backlog milestone Jan 23, 2018

@blackholegalaxy

This comment has been minimized.

blackholegalaxy commented Feb 6, 2018

As stated buy @gmfun, the solution by @UnwrittenFun works. But refreshing make the app crash. So I think this bug should really be addressed soon... Lazy load a module in a name router outlet is quite a common pattern in auxiliary routes...

@rohanrichards

This comment has been minimized.

rohanrichards commented Jul 16, 2018

I'm using @UnwrittenFun workaround, but I'm having trouble getting this work for child routes that require params. Any tips?

I'm trying something like this:

{ path: '', redirectTo: '/tabs/(profileoutlet:profile/5b1e0749f6f1f97634b68de2)', pathMatch: 'full' },
{
	path: 'tabs', component: TabsComponent, children: [
		{
			path: 'profile', component: TabsProxyComponent, outlet: 'profileoutlet',
			children: [
				{ path: ":id", loadChildren: "./pages/profile/view-profile/view-profile.module#ViewProfileModule" }
			]
		},
	]
}

My route is loading, however no params are making it to the component. I have tested the module outside of the tabs and can pass in params fine.

VamsiVempati added a commit to VamsiVempati/angular that referenced this issue Aug 20, 2018

fix(router): lazy loaded routes empty path with auxillary routes
Add a check for lazy loaded modules to fix errors on refreshing a lazy loaded route with auxillary routes

Closes angular#12842
@VamsiVempati

This comment has been minimized.

VamsiVempati commented Aug 21, 2018

Sorry folks, the above commit was to try this pull request (not by me) #25483 to see if it fixes the issue for me. Accidentally added closes tag, sorry

VamsiVempati added a commit to VamsiVempati/angular that referenced this issue Aug 21, 2018

fix(router): lazy load auxillary roots with empty base route
Add a null check to see if the modules are lazy loaded before returning the routes

Closes angular#12842
@VamsiVempati

This comment has been minimized.

VamsiVempati commented Aug 21, 2018

The above change (by me) seems to fix it for me though, cheers.

VamsiVempati added a commit to VamsiVempati/angular that referenced this issue Aug 21, 2018

fix(router): Remove non null assertion operator as it is replaced by …
…null check

Remove non null assertion operator as it is replaced by null check

Fixes angular#12842
@SvenSchoene

This comment has been minimized.

SvenSchoene commented Sep 12, 2018

What worked for me is two things:

  • Always have an empty-path redirection on all levels.
  • Use the full named-outlet-URL-syntax for redirection.

After hours and hours of debugging this I'm too tired to explain this more clearly, so let me just leave you with an example route-configuration I use here:

export const routes: Routes = [
    {
        path: '',
        redirectTo: '/index/(main:newsfeed//header:newsfeed)', // this is important because there are no cascading redirects, see: https://github.com/angular/angular/issues/10120
        pathMatch: 'full',
    },
    {
      path: 'index',
      component: IndexIndexComponent,
      children: [
        {
            path: '',
            redirectTo: '/index/(main:newsfeed//header:newsfeed)',
            pathMatch: 'full',
        },
        {
            path: 'newsfeed',
            loadChildren: "c/newsfeed-index/newsfeed-index.module#NewsfeedIndexModule",
            outlet: 'main',
        },
        {
            path: 'newsfeed',
            loadChildren: "c/me-header-index/me-header-index.module#MeHeaderIndexModule",
            outlet: 'header',
        },
      ]
    },
  ]

To be honest, while it is super-unintuitive and documentation and examples around this are missing entirely, I guess it actually makes sense that the Angular router would need the specific outlet and route for that outlet specified.
...or I'm just too tired and I can't see how stupid it is that this is necessary.

In any case, I can keep developing my application now... (after some sleep, of course!)

@cguilhermef

This comment has been minimized.

cguilhermef commented Sep 12, 2018

Great @SvenSchoene! It make sense to me. I've reached some situations where an empty-path was necessary to handle with secondary routes. I think you found the answer more clearly: secondary routes - or named outlets - need a path specified (in this case, an empty path) to the primary outlet .

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment