Search code examples
angularangular-routing

How do I use child routes in angular 17 angular routing


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: enter image description here 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?

Code post here if anyone wants to give it a shot


Solution

  • UPDATE:

    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.

    1. 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 its automatically take care in the constructor.

    2. 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.

    3. 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.

    4. You should only have one boostrapApplication in your code.

    5. 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.

    6. For the routing, you should have a <router-outlet/> below the tabs.

    7. You should navigate using relative to activated route.

       this.router.navigate(['./', routingMap[event.index]], {
         relativeTo: this.activatedRoute
       })
      
    8. You should get rid of the route contents since its 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>
      
    9. 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 }
       ];
      

    Github Repo




    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)

    If you application follows standalone methodology

    Validate that the above mentioned components have standalone: true set on them, only then the components will be discovered by routing.


    If you application follows modular methodology

    Validate that the above mentioned components are added to the declarations array of the AppModule, only then routing can discover these components.