Navigate to child of lazy loaded module angular 8 - javascript

My app-routing.module.ts
const routes: Routes = [
{ path: '', redirectTo: 'dashboard', pathMatch: 'full' },
{ path: 'dashboard', component: DashboardComponent },
{ path: 'updateBooking', loadChildren: () => import('./update-booking/update-booking.module').then(m => m.UpdateBookingModule) },
{ path: 'booking', loadChildren: () => import('./booking/booking.module').then(m => m.BookingModule) }
];
#NgModule({
imports: [RouterModule.forRoot(routes, { enableTracing: true })],
exports: [RouterModule]
})
export class AppRoutingModule { }
lazy loaded Booking module's routing:
const routes: Routes = [
{ path: '', redirectTo: 'bookingdashboard' },
{
path: 'bookingdashboard', component: BookingDashboardComponent,
children: [
{ path: '', redirectTo: 'associateinfo' },
{
path: 'associateinfo', component: AssociateInfoComponent
},
{
path: 'agenda', component: AgendaComponent
},
{
path: 'zone', component: ZoneComponent
},
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class BookingRoutingModule { }
I am on associate info page with url http://localhost:4200/booking/bookingdashboard/associateinfo
From this page when I try to navigate to agenda page using this._route.navigate(['../agenda' ]); I am getting error Cannot match any routes. URL Segment: 'agenda'
Error: Cannot match any routes. URL Segment: 'agenda'
However If I try to navigate from HTML file using [routerLink]="[ '../agenda']" its navigating to agenda page

You are navigating to only component specific route path, you should follow route as module-path/component-path
this._route.navigate(['booking/bookingdashboard/agenda' ]);

try
this._route.navigate(['/booking/bookingdashboard/agenda']);

After the link parameters array, add an object with a relativeTo
property set to the ActivatedRoute. The router then calculates the
target URL based on the active route's location.
constructor(private _router: Router, private route: ActivatedRoute){}
this._router.navigate(['../agenda'], { relativeTo: this.route })

Related

Angular 14 routes any route that is below parameters route (i.e. :id) are not able to route

My app-routing.module.ts contains parameter routes that lead to a distinct id. I found out that my wildcard path was broken while testing my routes.
After considerable testing, it turns out that using a different route below the parameter path also doesn't work.
app-routing.module.ts (original setup)
const routes: Routes = [
{
path: '',
pathMatch: 'full',
loadChildren: () =>
import('./features/home/home.module').then((m) => m.HomeModule),
},
{
path: 'about',
loadChildren: () =>
import('./features/about/about.module').then((m) => m.AboutModule),
},
{
path: 'contact',
loadChildren: () =>
import('./features/contact/contact.module').then((m) => m.ContactModule),
},
{
path: ':id',
loadChildren: () =>
import('./features/profile/profile.module').then(
(m) => m.ProfileModule
),
},
// PATH BELOW NOT WORKING 👇
{
path: '**',
redirectTo: '',
},
];
#NgModule({
imports: [
RouterModule.forRoot(routes, {
initialNavigation: 'enabledBlocking',
}),
],
exports: [RouterModule],
})
export class AppRoutingModule {}
app-routing.module.ts (testing by swapping some path setup)
const routes: Routes = [
{
path: '',
pathMatch: 'full',
loadChildren: () =>
import('./features/home/home.module').then((m) => m.HomeModule),
},
{
path: ':id',
loadChildren: () =>
import('./features/profile/profile.module').then(
(m) => m.ProfileModule
),
},
// PATH BELOW NOT WORKING 👇
{
path: 'about',
loadChildren: () =>
import('./features/about/about.module').then((m) => m.AboutModule),
},
{
path: 'contact',
loadChildren: () =>
import('./features/contact/contact.module').then((m) => m.ContactModule),
},
{
path: '**',
redirectTo: '',
},
];
#NgModule({
imports: [
RouterModule.forRoot(routes, {
initialNavigation: 'enabledBlocking',
}),
],
exports: [RouterModule],
})
export class AppRoutingModule {}
First of all, a redirectTo route must contain a pathMatch property, otherwise it will not route (it should not even compile)
Next, it's a bad practice to provide routes at the same level like so
/home/about
/home/contact
/home/:id
Technically, it works, but because it relies on the order of the provided routes. if your :id route is set first in the list, then about and contact become ids too.
So the best solution would be to just separate the routes like so
/home/about
/home/contact
/home/items/:id
Otherwise, you can use the canMatch guard (like canActivate), but again, I would consider this a bad practice. Just follow a RESTFul-like structure for your routes, that's the best and simplest option.

Is there a way I can render a 2 level nested component in Angular using `router-outlet`?

I have a sidebar with some links. The sidebar is located at the /dashboard route. The links on the sidebar are direct children to /dashboard. I now want to render the children of /dashboard inside the main router-outlet. I have no idea on how to approach this.
The following are some code snippets to elaborate my question further
My routing structure
const routes: Routes = [
{
path: '',
component: LoginComponent,
},
{
path: 'dashboard',
component: DashboardComponent,
children: [
{
path: 'roles',
component: RolesComponent,
},
{
path: 'workgroups',
component: WorkgroupsComponent,
children: [
{
path: 'savewg',
component: WgDetailsComponent,
},
]
},
{
path: 'users',
component: UsersComponent,
},
],
},
];
App component
<!-- Main app component -->
<div class="app-view">
<router-outlet></router-outlet>
</div>
Login.html
<button mat-raised-button color="warn" class="login-field" (click)="login(email, password)"
<!-- rest of code ommited for brevity -->
Login.ts
public login(email: string, password: string) {
this.router.navigate(['dashboard'], { replaceUrl: true });
}
Workgroup Component html
<button mat-raised-button color="warn" [routerLink]="['savewg']">
<mat-icon>add</mat-icon>
New
</button>
<!-- Code ommited for brevity -->
<router-outlet></router-outlet>
<div class="workgroup-filters">
<mat-form-field appearance="outline">
<!-- rest of Code ommited for brevity -->
When I click on the new button in the workgroup component, I want it to navigate me to the savewg component view and replace the content in the workgroup component.
Any suggestions on how I can tackle this will be appreciated
Modules are only allow one main router-outlet per module. You will have to create a separate module for workgroups path and lazy load it. The workgroups module will have its own routing file and its own router outlet where you will load all your routes from your workgroup module. See below stackblitz for a working example.
app-routing.module.ts
const routes: Routes = [
...
{
path: 'workgroups',
loadChildren: () => import('./workgroups/workgroups.module').then(m => m.WorkgroupsModule)
},
...
];
#NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule]
})
export class AppRoutingModule { }
workgroups-routing.module.ts
const routes: Routes = [
{
path: '',
component: WorkgroupsComponent,
children: [
{
path: 'savewg',
component: WgDetailsComponent
},
{
path: '**',
redirectTo: 'savewg',
pathMatch: 'full'
}
]
},
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class WorkgroupsRoutingModule { }
workgroups.module.ts
#NgModule({
imports: [
CommonModule,
WorkgroupsRoutingModule
],
declarations: [
WorkgroupsComponent,
WgDetailsComponent
]
})
export class WorkgroupsModule { }
Below are resources for lazy loading modules and a stackblitz example.
https://stackblitz.com/edit/angular-ivy-hbogtn
https://www.freakyjolly.com/angular-nested-routing-with-multiple-routeroutlet-using-loadchildren-having-own-router-modules-example-application/#.X3IQa3WYXmE
I found a better solution to this. It turns out that Angular will load the empty path route as the default route and there is no need to worry about router outlet anymore. I modified my app-routing.module.ts in the following way:
const routes: Routes = [
{
path: '',
component: LoginComponent,
},
{
path: 'dashboard',
component: DashboardComponent,
children: [
{
path: 'roles',
component: RolesComponent,
},
{
path: 'workgroups',
children: [
{
path: 'savewg',
component: WgDetailsComponent,
},
{
path: '',
component: WorkgroupsComponent,
},
],
},
{
path: 'users',
component: UsersComponent,
},
],
},
];
As you can see, I've added an empty path as a child in the
workgroups component This may not be perfect, more approaches and
solutions are welcome.

Angular 8.x routing with named outlets

I try to configure routing in angular 8.x application, with lazy loading and named outlets. I have the next configuration:
main-layout.html
<header>
<app-top-menu></app-top-menu>
</header>
<mat-sidenav-container autosize="true" id="app-main-layout">
<mat-sidenav opened mode="side">
<app-left-menu></app-left-menu>
</mat-sidenav>
<router-outlet name="toolbar"></router-outlet>
<div id="app-layout-content">
<router-outlet></router-outlet>
</div>
</mat-sidenav-container>
app-router.module.ts
const routes: Routes = [
{
path: '', component: MainLayoutComponent, canActivate: [RouteGuardService],
children: [
{
path: 'databases',
loadChildren: () => import('./feature-modules/database-search/database-search.module')
.then(m => m.DatabaseSearchModule)
}
]
}
];
#NgModule({
imports: [RouterModule.forRoot(routes, { enableTracing: true })],
exports: [RouterModule]
})
export class AppRoutingModule { }
There is a lazy loaded module router:
databases-search-routing.module.ts
const routes: Routes = [
{
path: 'index',
component: DatabaseListComponent,
children: [
{
path: '',
component: DatabaseListActionsMenuComponent,
outlet: 'toolbar'
}
]
},
{
path: 'mappings',
component: MappingsComponent,
children: [
{
path: '',
component: DatabaseListActionsMenuComponent,
outlet: 'toolbar'
}
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class DatabaseSearchRoutingModule { }
The aim here is to load different toolbar for different views. So /databases/index should load DatabaseListComponent into 'main' router outlet and DatabaseListActionsMenuComponent into named 'toolbar' outlet.
However, it is not working.
The main router outlet is populated correctly but the named outlet isn't. I can't figure out what I'm doing wrong.
What is the right configuration for this case?
You should try to put the primary outlet routes, and the toolbar outlet routes at the same depth, and have a componentless parent route for both, like this:
const routes: Routes = [{
path: 'index',
children: [{
path: '',
component: DatabaseListComponent
}, {
path: '',
component: DatabaseListActionsMenuComponent,
outlet: 'toolbar'
}
]
}, {
path: 'mappings',
children: [{
path: '',
component: MappingsComponent
}, {
path: '',
component: DatabaseListActionsMenuComponent,
outlet: 'toolbar'
}
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class DatabaseSearchRoutingModule {}

Angular routing - routing to a lazy module child path does not initiate the component

In my app-routing.module I have a lazy module:
const appRoutes: Routes = [
{ path: 'profile/:id',
loadChildren: './profile/profile-standalone/profile-standalone.module#ProfileStandaloneModule',
}
];
Here is my profile--standalone-routing.module-
const routes: Routes = [
{
path: '',
component: ProfileStandaloneComponent,
children: [
{
path: '',
redirectTo: 'outputa',
pathMatch: 'full'
},
{
path: 'outputa',
component: ProfileOutputComponent
}
]
}
];
#NgModule({
imports: [RouterModule.forChild(routes)],
exports: [RouterModule]
})
export class ProfileStandaloneRoutingModule { }
But when I go to url "localhost:4200/profile/123/outputa", my "ProfileOutputComponent" does not get called.
Any idea how to make it work?
Try this.
const routes: Routes = [
{
path: 'outputa',
component: ProfileOutputComponent
];

Lazy loaded module base template

In app.module.ts I load 2 lazy modules like this
const appRoutes: Routes = [
{ path: 'anonym', loadChildren: './anonym/anonym.module#AnonymModule' },
{ path: 'user', loadChildren: './user/user.module#UserModule', canActivate: [AuthGuard] }
];
In app.component.html I can write some base html. My question - is there any way to have base html for my UserModule?
I have tried to create user.component.ts and load it like in app.module.ts
import { UserComponent } from './user.component';
#NgModule({
declarations: [UserComponent],
bootstrap: [UserComponent]
});
but it's not show me user.component.html
In your user module define a base route with an empty path, and then define the sub-paths as children.
const ROUTES: Routes = [
{
path: '',
component: UsersComponent,
children: [
{
path: '',
pathMatch: 'full',
redirectTo: 'login'
}, {
path: 'login',
component: LoginComponent
}, {
path: 'logout',
component: LogoutComponent
}
]
}
];
The UsersComponent will now be used as a base component, and if you navigate to just /users it will redirect to the /users/login path.
Make sure your UsersComponent has a template with <router-outlet></router-outlet> so the child routes.
#NgModule({
imports: [
RouterModule.forChild(ROUTES)
],
exports: [
RouterModule
]
})
export class UsersModule {
}

Categories

Resources