How to properly lazyload component in angular?

74 Views Asked by At

I am stuck with some simple route management in Angular : I have this first module :

import { NgModule } from '@angular/core';
import { Routes } from '@angular/router';
import { RouterModule } from '@angular/router';
import { LayoutComponent } from './ui/components/layout/layout.component';


const routes: Routes = [{ path: '**',
     component: LayoutComponent,
     children: [    { path: '', redirectTo: '/posts', pathMatch: 'full'},
    { path: 'posts',loadChildren: './posts/posts.module#PostsModule' }] }];

@NgModule({
  imports: [RouterModule.forRoot(routes)
     ],
  exports: [RouterModule]
})
export class AppRoutingModule { }

And the "PostModule" which should show simple "it works" component :

import { NgModule } from '@angular/core';\n
import { Routes } from '@angular/router';\n
import { RouterModule } from '@angular/router';
import { PostsComponent } from './containers/posts/posts.component';
import { ProfileComponent } from './containers/profile/profile.component';

const routes: Routes = [{ path: '', component: PostsComponent },{ path: ':profileId', component: ProfileComponent },];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class PostsRoutingModule { }

But none of the route

http://localhost:4200/posts/

http://localhost:4200/posts/1

show the expected content

I suppose I have miss something simple my app.component look like this:

   <router-outlet>
      <router-outlet></router-outlet>
   </router-outlet>

I have read some poste on "lazy loading", but what I wrote seem coherent from what I learned until now, where is the mistake ?

3

There are 3 best solutions below

1
On BEST ANSWER

The problem seems to be in the way you structured the routings. It should be configured like this:

const routes: Routes = [
  {
    path: '',
    component: LayoutComponent,
    children: [
      { path: 'posts', loadChildren: './posts/posts.module#PostsModule' }
    ]
  },
  { path: '**', redirectTo: '/', pathMatch: 'full' }
];

The idea of "path: '**'" is to handle any non-defined route you entered in the browser (i.e. /hello-world) and redirects to the root or any other defined route you choose.

So in the way you have it defined, the routing is always capturing the navigation and showing the LayoutComponent.

3
On

First try to do the following:

   <router-outlet>
      <p>Layout Component loaded</p>
      <router-outlet></router-outlet>
   </router-outlet>

Then, if something is written in your landing page, put the second router-outlet in your LayoutComponent.

In order to use multiple outlets side by side in one template, you need to use named router outlets.

0
On

Which Angular version are you using? Have you tried the following?

const routes: Routes = [{
  path: '**',
  component: LayoutComponent,
  children: [
    { path: '', redirectTo: '/posts', pathMatch: 'full' },
    { path: 'posts', loadChildren : () => import('./posts/posts.module').then(x => x.PostsModule) }
  ]
}];



Update:

The component added to a router outlet by the router is added below the outer router-outlet, therefore adding something inside the is pointless.

The inner router-outlet needs to be moved into LayoutComponent component, which is added to by the router.