How do I create child routes for a tab page using angular?
app.component.html
<main class="main">
<div class="content container-fluid">
<router-outlet></router-outlet>
<app-header [hidden]="!this.headerIsHidden"></app-header>
<app-job-details [hidden]="!this.jobDetailsIsHidden"></app-job-details>
<app-notification-details [hidden]="!this.notificationDetailsIsHidden"></app-notification-details>
</div>
</main>
header.component.html
<div class="background">
<p class="text-center">Job Tracker</p>
<p-tabView class="tab" [hidden]="isHidden" (onChange)="handleChange($event)" [(activeIndex)]="headerIndex">
<p-tabPanel header="View Jobs Applied For">
<app-job-applied-for></app-job-applied-for>
</p-tabPanel>
<p-tabPanel header="Add Job Applied For">
<app-add-job-applied-for></app-add-job-applied-for>
</p-tabPanel>
<p-tabPanel header="Remove Job Applied For">
<app-remove-job-applied-for></app-remove-job-applied-for>
</p-tabPanel>
<p-tabPanel header="View Notification" [disabled]="notificationsIsDisabled">
<app-view-notification></app-view-notification>
</p-tabPanel>
<p-tabPanel header="Set Notification" [disabled]="notificationsIsDisabled">
<app-set-notification></app-set-notification>
</p-tabPanel>
<p-tabPanel header="Remove Notification" [disabled]="notificationsIsDisabled">
<app-remove-notification></app-remove-notification>
</p-tabPanel>
</p-tabView>
</div>
app.routes.ts
export const routes: Routes = [
{ path: 'app-header', component: HeaderComponent, children:[
{ path: '',redirectTo: 'app-header', pathMatch: 'full'},
{ path: 'app-job-applied-for', component: JobAppliedForComponent},
{ path: 'app-add-job-applied-for', component: AddJobAppliedForComponent},
{ path: 'app-remove-job-applied-for', component: RemoveJobAppliedForComponent},
{ path: 'app-view-notification', component: ViewNotificationComponent},
{ path: 'app-set-notification', component: SetNotificationComponent},
{ path: 'app-remove-notification', component: RemoveNotificationComponent},
]},
{ path: 'app-job-details', component: JobDetailsComponent },
{ path: 'app-job-details/:id', component: JobDetailsComponent },
{ path: 'app-notification-details', component: NotificationDetailsComponent },
{ path: 'app-notification-details/:id', component: NotificationDetailsComponent },
{ path: 'app-edit-job', component: EditJobComponent },
{ path: 'app-edit-job/:id', component: EditJobComponent },
{ path: 'app-edit-notification', component: EditNotificationComponent },
{ path: 'app-edit-notification/:id', component: EditNotificationComponent }
];
when I remove all child routes except for the first child route, the header page displays, I can navigate to all tabs, but I don't have routing for the other tabs. When I add router outlet to the header component, I don't get an error in the console, but routing doesn't work either(i get a blank screen). When I try to running it without adding a routeroutlet to the header, and leaving all paths in tack, I get this error: I strongly believe the issue is in app.routes.ts, but I don't know how to fix it. What do I need to do to get child routing working?
There is a lot of stuff which needs to be corrected, will just run through few of them, you need to go to Angular docs and give a good read.
You should import a service/component using private activatedRoute: ActivatedRoute
, this will do the importing automatically, so you can get rid of the extra code inside the constructor, since it's automatically taken care of in the constructor.
You should not import all the components/services instead, you should only import when an error comes, the main thing to know is that, if the component is from routing, there is no need to import it.
Instead of importing component in the constructor (tight coupling), use @Input
and @Output
also when routing is involved you need to use event bus
, reference stackblitz, always aim for loose coupling, since the component cannot work freely without the parent due to dependency.
You should only have one boostrapApplication
in your code.
You should create a module which contains the imports shared by multiple components, make sure the imports are used everywhere in your application, these eases the work of importing multiple times.
For the routing, you should have a <router-outlet/>
below the tabs.
You should navigate using relative to activated route.
this.router.navigate(['./', routingMap[event.index]], {
relativeTo: this.activatedRoute
})
You should get rid of the route contents since it's already taken care of by routing.
<div class="background">
<p class="text-center">Job Tracker</p>
<p-tabView
class="tab"
[hidden]="isHidden"
(onChange)="handleChange($event)"
[(activeIndex)]="headerIndex"
>
<p-tabPanel header="View Jobs Applied For"> </p-tabPanel>
<p-tabPanel header="Add Job Applied For"> </p-tabPanel>
<p-tabPanel header="Remove Job Applied For"> </p-tabPanel>
<p-tabPanel header="View Notification"> </p-tabPanel>
<p-tabPanel header="Set Notification"> </p-tabPanel>
<p-tabPanel header="Remove Notification"> </p-tabPanel>
</p-tabView>
<router-outlet />
</div>
Finally, the routing should have default redirects so that the end user, does not end up in a blank screen when first loading the application.
export const routes: Routes = [
{ path: '', redirectTo: 'app-header', pathMatch: 'full' },
{
path: 'app-header', component: HeaderComponent, children: [
{ path: '', redirectTo: 'app-job-applied-for', pathMatch: 'full' },
{ path: 'app-job-applied-for', component: JobAppliedForComponent },
{ path: 'app-add-job-applied-for', component: AddJobAppliedForComponent },
{ path: 'app-remove-job-applied-for', component: RemoveJobAppliedForComponent },
{ path: 'app-view-notification', component: ViewNotificationComponent },
{ path: 'app-set-notification', component: SetNotificationComponent },
{ path: 'app-remove-notification', component: RemoveNotificationComponent },
]
},
{ path: 'app-job-details', component: JobDetailsComponent },
{ path: 'app-job-details/:id', component: JobDetailsComponent },
{ path: 'app-notification-details', component: NotificationDetailsComponent },
{ path: 'app-notification-details/:id', component: NotificationDetailsComponent },
{ path: 'app-edit-job', component: EditJobComponent },
{ path: 'app-edit-job/:id', component: EditJobComponent },
{ path: 'app-edit-notification', component: EditNotificationComponent },
{ path: 'app-edit-notification/:id', component: EditNotificationComponent }
];
The error "Cannot read properties of undefined (reading "ecmp")" is related to you using a component that is not imported/declared.
I think the issue is due to one of the components (JobAppliedForComponent
, AddJobAppliedForComponent
, RemoveJobAppliedForComponent
, RemoveJobAppliedForComponent
, ViewNotificationComponent
, SetNotificationComponent
, RemoveNotificationComponent
)
Validate that the above mentioned components have standalone: true
set on them, only then the components will be discovered by routing.
Validate that the above mentioned components are added to the declarations
array of the AppModule
, only then routing can discover these components.