I'm using Angular 6.0.3. I have a sub-module called "Admin" with three components. Admin's root component ("AdminComponent") route works fine (path: ""
), but I can't seem to trigger any of the others. Why can't Angular find my routes?
routes.ts
import { Routes } from "@angular/router";
import { SplashComponent } from "./splash/splash.component";
import { LoginComponent } from "./login/login.component";
import { WatchComponent } from "./watch/watch.component";
import { AdminComponent } from "./admin/admin/admin.component";
import { HomeComponent as AdminHomeComponent } from "./admin/home/home.component";
import { AddSongComponent } from "./admin/add-song/add-song.component";
import { AdminGuard } from "./auth/admin.guard";
export const appRoutes: Routes = [
{
path: "",
children: [
{ path: "", component: SplashComponent, pathMatch: "full" },
{ path: "login", component: LoginComponent, pathMatch: "full" },
{ path: "watch", component: WatchComponent, pathMatch: "full" },
{
path: "admin",
component: AdminComponent,
pathMatch: "full",
canActivate: [AdminGuard],
children: [
{
path: "",
component: AdminHomeComponent,
pathMatch: "full",
outlet: "admin"
},
{
path: "add-song",
component: AddSongComponent,
pathMatch: "full",
outlet: "admin"
}
]
}
]
}
];
admin/admin/admin.component.html
<router-outlet name='admin'></router-outlet>
admin/home/home.component.html
<div>
<a mat-raised-button [routerLink]="['add-song']">Add new song</a>
</div>
note: I've also tried [routerLink]="[{ outlets: { admin: ['add-song'] } }]
, still route not found.
I would recommend you to look at Lazy-loading
feature while loading sub modules, which is the correct way to load when you have many modules.
In your case you have admin module as a sub module, so here is the routing Configuration,
RouterModule.forRoot([
{ path: '', redirectTo: 'splash', pathMatch: 'full' },
{ path: 'splash', component: SplashComponent },
{ path: 'admin', loadChildren: './admin/admin.module#AdminModule' },
{ path: '**', component: NotFoundComponent }
], { enableTracing: true })]
and the Admin.module routing is as follows,
RouterModule.forChild([
{
path: '', component: AdminComponent,
children: [
{ path: '', component: AdminHomeComponent }
,
{ path: 'add-song', component: AddSongComponent}]
}
])
]
WORKING STACKBLITZ DEMO
ROUTES:
Splash
https://nested-routes-angular-lazyloading.stackblitz.io/splash
Admin
https://nested-routes-angular-lazyloading.stackblitz.io/admin
Admin-AddSong
https://nested-routes-angular-lazyloading.stackblitz.io/admin/add-song
Have you tried to create Admin related components in its own module?
Then you can create a admin-routing.module.ts
const adminRoutes: Routes = [
{
path: '',
component: AdminComponent,
children: [
{
path: '',
children: [
{ path: 'add-song', component: AddSongComponent },
{ path: 'something-else', component: SomeOtherComponent },
{ path: '', component: AdminDefaultComponent }
]
}
]
}
];
@NgModule({
imports: [
RouterModule.forChild(adminRoutes)
],
exports: [
RouterModule
]
})
export class AdminRoutingModule {}
Then in your main app-routing.module
you can refer to it as
const appRoutes: Routes = [
{ path: '', component: SplashComponent },
{ path: 'login', component: LoginComponent },
{
path: 'admin',
loadChildren: 'app/admin/admin.module#AdminModule',
},
{ path: '**', component: SomeOtherComponent }
];
@NgModule({
imports: [
RouterModule.forRoot(appRoutes)
],
exports: [
RouterModule
],
})
export class AppRoutingModule { }
edit: I noticed that you did create its own sub module, so you'll need to create a routing-module for this sub-module.
This might be late reply, but i would like to focus on 1 important thing, angular compiler is very smart which detects on which root you currently on.So if you are calling any nested route from .html template it will automatically checks your current route in the url and what ever route you want this will simply append this to current route.
In simple terms, What you are trying to do in your code from admin/home/home.component.html
you are trying to trigger add-song
route and it will give you result as admin/add-song
doesn't exist.This is pretty much expected though
sharing routes config. for children and some other code snippet.
children: [
{
path: "admin-home",
component: AdminHomeComponent,
pathMatch: "full",
outlet: "admin"
},
{
path: "add-song",
component: AddSongComponent,
pathMatch: "full",
outlet: "admin"
},
{path: '',
redirectTo:'admin-home',
pathMatch: 'full'}
]
now from your admin/home/home.component.html
use below routerLink
<div>
<a mat-raised-button [routerLink]="['/add-song']">Add new song</a>
</div>
Untill now you were trying to add relative path, In angular specially in routerLink, it will detect current path and will append expected path to the end of your current path.so it will give you error.So try to provide absolute path in your nested routes.
But this.router.navigate() method won't understand it's current route automatically.It always starts route from root route.i.e if you are trying to call nested path from .ts file then angular won't recognize current path.So if you willing to tell angular that which is current route then from .ts file you can do something like this
import { ActivatedRoute, Router } from '@angular/router';
...
constructor(private route: ActivatedRoute, private router: Router) { }
...
this.router.navigate(['./add-song'], {relativeTo: this.route});
One more thing is like <a mat-raised-button [routerLink]="['add-song']">Add new song</a>
this is as same as <a mat-raised-button [routerLink]="['./add-song']">Add new song</a>
Or <a mat-raised-button [routerLink]="['../add-song']">Add new song</a>
this is relative path, you must use absolute path
Otherwise try calling your route from .ts component without relativeTo
property and relative path.
Hope this may work for you
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With