Angular named router outlet no matched routes - javascript

I am working on an application that uses lazy-loaded modules for each main part of the app. I have one that I two router outlets in a primary one and one called details.
const routes: Routes = [
{ path: '', component: BooksComponent, resolve: {books: BooksResolver},
{ path: ':id', component: BookDetailsComponent, resolve: { book: BookResolver},outlet: "details"},
];
with the HTML like below
<router-outlet></router-outlet>
<router-outlet namme="details"></router-outlet>
Then each book item I have a router link like below
[routerLink]="['/', { outlets: { details: [book.id] } }]"
When I click on an item in I get the following error: ERROR Error: Uncaught (in promise): Error: Cannot match any routes. URL Segment: '53'. Currently I have the details displaying in the primary router outlet but I can not get the details to show when a user clicks on the book item. I am not sure why this is not working I looked in the documentation and This seems to be the correct way of doing it haveing all routes at the same level. ANy help would be appreciated.

I think you have a problem with multiple exits, so LET me give you a little example that I hope makes sense to you
{
path: 'a', component: AComponent, children: [
{path: 'd', component: DComponent},
{path: 'c', component: CComponent,outlet:'right'},
// a/(d//right:c)
]
},
In the component AComponent
<a [routerLink]="['./',{outlets:{primary:['d'],right:['c']}}]">d/c</a>
<router-outlet></router-outlet>
<router-outlet name="right"></router-outlet>
Multiple egress can be regarded as child routes

Related

Vue router fails to load child route

I am trying to set up router in my Vue app. Everything seemed to work fine until i started to try implementing children routes. Now when i try to access child route i get an error message along with some warnings:
What happens when i click on child router-link
My router setup:
const router = createRouter({
history: createWebHistory(),
routes: [
{ path: '/', redirect: '/welcome' },
{
name: 'welcome',
path: '/welcome',
component: WelcomePage
},
{
name:'noteLists',
path: '/noteLists',
component: NoteListLinks,
children: [
{
name:'noteListSheets',
path: ':id',
components: FullNoteSheet
}
]
}
],
linkActiveClass: 'active'
});
All other route links work fine.
The components template where child links are used and rendered looks like that:
<template>
<router-link
:to="setNoteListLink(entry.id)"
:key=entry.id
v-for="entry in notesListEntry"
>
{{entry.name}}
</router-link>
<router-view></router-view>
Function setNoteListLink just creates a links like '/noteList/1'.
The error says that it "Cannot read property 'writeDebug' of undefined" and writeDebug is a method on a component that it tries to load when i click on the route (FullNoteSheet), so i assume there is something wrong with the component and not the router. But component works just fine if i try to load it separately, by jst putting it in App component template.
If you have dealt with such issues and know the solution please let me know.
You have a typo in the noteListSheets route; It should be component: FullNoteSheet not components: FullNoteSheet

Multiple named router-outlet - component imported but not initialized and rendered

I'm using multiple named angular 8 router-outlet in a web app. All the routerLink seems to work as it changes the URL but components in my 2nd router-outlet are imported but not initialized nor rendered.
I made a Stackblitz available here : https://stackblitz.com/edit/ng-multiple-router-outlet?file=src/app/app.component.ts
As you can see, when you click on the sidebar, under photos you have a second navigation level by clicking on Google or Facebook but nothing is rendered.
In modules, components used in other modules and RouterModule are well exported to be accessible, I don't see what I've done wrong.
I tried to declare the routes with both forRoot and forChild methods, I put some logs, but I'm running out of clues.
Thanks for your help !
Angular router is pretty simple once you understand how nested routes works there.
Let's imagine a simple configuration:
RouterModule.forRoot([
{
path: '',
component: HomeComponent,
children: [
{ path: 'child', component: ChildComponent }
]
}
])
How would you use router-outlet to cover all routes above?
app.component.html
\
contains
\
<router-outlet></router-outlet>
\/
renders
\
HomeComponent
home.component.html
\
contains
\
<router-outlet></router-outlet>
renders
\
ChildComponent
The main takeaway here is that router-outlet renders component depending on router context. Once it renders component a new context is created and all router-outlet's declared at this level will look at children configuration.
The same is true for named routes.
You've generated the link like:
(selection:facebook//sidebar:photos)
It means that these named routes should be at the same root level. But you defined <router-outlet name="selection"></router-outlet> at nested level inside rendered by router LibraryComponent.
Let's add this outlet at the same level as 'sidebar':
<router-outlet name="sidebar"></router-outlet>
<router-outlet name="selection"></router-outlet>
and it actually works stackblitz
Now let's come back to your attempt. If you want to render selection components inside selection.component.html then you should be using nested named routed links:
selection.component.html
[routerLink]="['.', { outlets: { selection: [routeName] } }]"
\/
relative path
The above binding will generate nested links like (sidebar:photos/(selection:facebook))
Now you need to move SelectionRoutes configuration to children property of photos path:
selection.module.ts
imports: [
CommonModule,
RouterModule, //.forChild(SelectionRoutes)
],
sidebar.routes.ts
import { SelectionRoutes } from '../selection/selection.routes';
...
export const SidebarRoutes: Route[] = [
{ path: 'photos', component: LibraryComponent, outlet: 'sidebar', children: SelectionRoutes },
Stackblitz Example
Update
In order to make facebook as a default subroute you create a route with redirectTo option like:
export const SelectionRoutes: Route[] = [
{ path: 'facebook', component: FacebookComponent, outlet: 'selection' },
{ path: 'google', component: GoogleComponent, outlet: 'selection' },
{ path: '', redirectTo: '/(sidebar:photos/(selection:facebook))', pathMatch: 'full', },
]
Stackblitz Example

When are routed components initialized?

I have the following route:
path: ':id', component: ViewBookPageComponent },
And when added it produces the error:
Error: Cannot read property 'id' of null
I'm not performing a null check in the component since the property will be available when the component is navigated to and in this case the auth guard is also keeping rerouting to login prior to any of the book routes being shown.
This is a stacblitz demo:
https://stackblitz.com/edit/angular-ngrx-slice-demo-fork-with-id-route?file=src%2Fapp%2Fbooks%2Findex.ts
If I comment out the route, the error no longer appears, so it seems Angular is instantiating the component prior to it being routed to.
Is the following fix your problem?
const routes: Routes = [
{
path: 'find',
component: FindBookPageComponent,
},
children:[
{
path: 'result',
component: SearchResultComponent,
},
children:[
{
path: 'book/:id',
component: ViewBookPageComponent ,
}
]
]
]
The AuthGuard is not protecting the route. It needs to be declared within the Book module itself. See this question for more details.

Angular 6: How to use multiple loadChildren with same route?

I have something like:
const routes: Routes = [
{
path: ':path', component: SiteRoot, children: [
{ path: '', loadChildren: '../modules/maple/template.module#TemplateModule' }
]
}
];
I wish to use this :path url to match multiple module dynamically. each module have there own internal Route.
Is there any way I can achieve this?
I tried ViewContainerRef with ResolveComponentFactory but it does not work with module only component. Event with NgModuleFactoryLoader, Routes cannot be applied.
EDIT, to make everything clear:
What I am trying to achieve is to have different module display on same route path. For example user can see user dashboard at "home" path, and admin can see admin dashboard at "home" path as well.
This feature is defined by business logic, so, I cannot change admin dashboard to another url
I think you are trying to create your routing module incorrectly. Anyway, you should write why you need this. I'll try to answer. Every module should have it's own path, so routing module should be strict and static. If you trying it for security, use guards and hide item from menu component.
If you need URLs like this: "/username1/profile", "/username2/profile" you can simply use code like yours, or use lazy loading. create routing file for parent module:
{ path: ':username', loadChildren: '../users/user.module#UserModule' }
Than create routing file for child module:
{ path: '', loadChildren: 'UserComponent', children: [
{ path: '', redirectTo: 'profile' },
{ path: 'profile', component: ProfileComponent}
]
}
Updated By your case:
by your case you can change your HTML file. For example in app.component.html if your code is:
<div>
<router-outlet></router-outlet>
</div>
You can change it with:
<div *ngIf="isLoggedIn | async">
<admin-panel></admin-panel>
</div>
<div *ngIf="(!isLoggedIn | async)">
<router-outlet></router-outlet>
</div>

Angular 4 lazy load module doesn't work with named child outlet

I am trying to implement lazy loading for a module. This module has a bunch of child routes with a unique outlet name. This doesn't seem to work when I try to visit the routes.
This can be seems from this example that I saved: https://plnkr.co/edit/NNXAoZItM00RIIxzemts?p=preview
You can see that I have the child route set to
{ path: 'list', component: HeroListComponent, outlet: 'abc' },
in hero-routing.module.ts
and router outlet to:
<router-outlet name="abc"></router-outlet>
in hero.component.ts
I should be able to visit localhost:3000/heroes/(abc:list) when I am running it locally, but it doesn't seem to work.
Note: You can run the plunker example locally by download the zip file and running npm install then npm start.
The child routes do not seem to work with default unamed routes.
Change the lazy loaded module routes to include a redirect from default unamed route to a named route.
const routes: Routes = [
{ path: '', redirectTo: 'start', pathMatch: 'full' },
{ path: 'start', component: HeroComponent,
children: [
{ path: 'list', component: HeroListComponent, outlet: 'abc' },
{ path: ':id', component: HeroDetailComponent }
]
}
];
Finally change the navigation link for 'heroes' lazy loaded module to include the named outlet information. Be sure to specify the complete url as '/heroes/start', do not leave it to the default '/heroes'.
<a [routerLink]="['/heroes/start',{outlets: {abc:['list']}}]"
routerLinkActive="active">Heroes</a>

Categories

Resources