This is in Angular 12. I have a payments controller in ClientApp/src/app with (not showing all code) payments.module.ts:
import { NgModule } from '@angular/core';
import { RouterModule } from '@angular/router';
import { PaymentsComponent } from "./payments.component";
@NgModule({
imports: [RouterModule.forChild([{path: 'payments',component: PaymentsComponent}])],
declarations: [PaymentsComponent]
})
export class PaymentsModule {}
and payments.component.ts:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-payments',
templateUrl: './payments.html'
})
export class PaymentsComponent implements OnInit {
constructor(...) { ... }
ngOnInit(): void {... });
}
}
PaymentsModule is only referenced in app.module.ts:
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
...
import { AppComponent } from './app.component';
import { AppRouterModule } from './app-router.module';
import { PaymentsModule } from "./payments/payments.module";
....
@NgModule({
declarations: [AppComponent],
imports: [
HttpClientModule,
PaymentsModule,
AppRouterModule,
.....
],
...
bootstrap: [AppComponent],
})
export class AppModule {}
There is no reference to PaymentsComponent in app-router.module.ts. File app.component.html has an <app-menu>
selector, and that selector contains a mat-menu-item which has no problem navigating to Payments:
<button mat-menu-item [routerLink]="['/payments']">Payments</button>
I want to place a process-payment component within the payments component, however I do not want the process-payment component to be a child component of payments. I want to navigate to process-payment directly via another mat-menu-item. The code for process-payment is as basic as what I've shown above for the two payments files, and I added the same references in app.module.ts:
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
...
import { AppComponent } from './app.component';
import { AppRouterModule } from './app-router.module';
import { PaymentsModule } from "./payments/payments.module";
import { ProcessPaymentModule } from "./payments/process-payment/process-payment.module"; //added here
....
@NgModule({
declarations: [AppComponent],
imports: [
HttpClientModule,
PaymentsModule,
ProcessPaymentModule, //added here
AppRouterModule,
.....
],
...
bootstrap: [AppComponent],
})
export class AppModule {}
However a new menu item cannot find my new component, I get a 404 Not found error with no details:
<button mat-menu-item [routerLink]="['/payment/process-payment']">Process Payment</button>
I've tried different paths for routerLink, but always get redirected to my page not found component. Not understanding how/why the new component cannot be found, the process-payment structure and reference is the same as payments. Can anyone help or shed some light as to the problem, other than me as the problem? :) Thanks, BB.
CodePudding user response:
I think you're trying to have nested routes. Basically, you should have a <router-outlet>
inside payments.component.ts
and add children
to your path payments
in payments.module.ts
.
payments.component.html
<h1>Payments</h1>
<a mat-menu-item [routerLink]="['process-payment']">Process Payment</a>
<!-- Children route will be inserted here -->
<router-outlet></router-outlet>
payments.module.ts
:
@NgModule({
imports: [
RouterModule.forChild([
{
path: 'payments',
component: PaymentsComponent,
children: [
{
path: 'process-payment',
component: ProcessPaymentComponent
}
]
}
])
],
declarations: [PaymentsComponent]
})
export class PaymentsModule {}
If you want to navigate to process-payment from app-component or elsewhere, the routerLink
would be ['/payments/process-payment']
You can find the documentation for nesting routes here: https://angular.io/guide/router#nesting-routes
EDIT
If you do not want nested routes and only keep them flat with a single router-outlet, then you just need to add a new route for ProcessPaymentComponent
.
@NgModule({
imports: [
RouterModule.forChild([
{
path: 'payments',
component: PaymentsComponent
},
{
path: 'payment/process-payment',
component: ProcessPaymentComponent
}
])
],
declarations: [PaymentsComponent]
})
export class PaymentsModule {}
Then just link to the page like you tried before:
<button mat-menu-item [routerLink]="['/payment/process-payment']">Process Payment</button>