Sorry for my bad english :/ I'm trying to build a simple online shop app with Angular, but so far when I try to access the two routes (home and 'carrinho' [portuguese for cart]) it gives me the error 'Error: NG04002: Cannot match any routes. URL Segment' and the browser redirects to localhost:4200 and not to the route I desire. The localhost:4200/carrinho should show the 'carrinho works!' sentence just to be sure thats working, but instead I have the error and redirects me to localhost:4200, same for home. So, any of these two are working. I'm facing bad things these days, so my attention may have ignored something, I tried to find whatever could be wrong and fix it, even visiting several Stack Overflow Threads here, but couldn't.
app-routing-module.ts - (src/app) folder
import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { CarrinhoComponent } from './pages/carrinho/carrinho.component'
import { HomeComponent } from './pages/home/home.component';
const routes: Routes = [
{
path: 'home',
component: HomeComponent,
},
{
path: 'carrinho',
component: CarrinhoComponent,
},
{ path: '', redirectTo: '/home', pathMatch: 'full' },
];
@NgModule({
imports: [RouterModule.forRoot(routes)],
exports: [RouterModule],
})
export class AppRoutingModule {}
app-module.ts - (src/app) folder
import { NgModule } from '@angular/core';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatGridListModule } from '@angular/material/grid-list';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { MatMenuModule } from '@angular/material/menu';
import { MatButtonModule } from '@angular/material/button';
import { MatCardModule } from '@angular/material/card';
import { MatIconModule } from '@angular/material/icon';
import { MatExpansionModule } from '@angular/material/expansion';
import { MatTreeModule } from '@angular/material/tree';
import { MatListModule } from '@angular/material/list';
import { MatToolbarModule } from '@angular/material/toolbar';
import { MatTableModule } from '@angular/material/table';
import { MatBadgeModule } from '@angular/material/badge';
import { MatSnackBarModule } from '@angular/material/snack-bar';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { HeaderComponent } from './components/header/header.component';
import { HomeComponent } from './pages/home/home.component';
import { ProductsHeaderComponent } from './pages/home/components/products-header/products-header.component';
import { FiltersComponent } from './pages/home/components/filters/filters.component';
import { CarrinhoComponent } from './pages/carrinho/carrinho.component';
@NgModule({
declarations: [
AppComponent,
HomeComponent,
HeaderComponent,
ProductsHeaderComponent,
FiltersComponent,
CarrinhoComponent,
],
imports: [
BrowserModule,
AppRoutingModule,
BrowserAnimationsModule,
MatSidenavModule,
MatGridListModule,
MatMenuModule,
MatButtonModule,
MatCardModule,
MatIconModule,
MatExpansionModule,
MatTreeModule,
MatListModule,
MatToolbarModule,
MatTableModule,
MatBadgeModule,
MatSnackBarModule,
HttpClientModule
],
exports: [
MatSidenavModule,
MatGridListModule
]
})
export class AppModule { }
home-component.ts
import { Component } from '@angular/core';
import { MatSidenavModule } from '@angular/material/sidenav';
import { MatGridListModule } from '@angular/material/grid-list';
import { ProductsHeaderComponent } from './components/products-header/products-header.component';
import { FiltersComponent } from './components/filters/filters.component';
import { ProductBoxComponent } from './components/product-box/product-box.component';
const ROWS_HEIGHT: { [id: number]: number } = { 1: 400, 3: 335, 4: 350 };
@Component({
selector: 'app-home',
standalone: true,
imports: [ProductBoxComponent, FiltersComponent, ProductsHeaderComponent, MatSidenavModule, MatGridListModule],
templateUrl: './home.component.html',
styleUrl: './home.component.css'
})
export class HomeComponent {
cols = 3;
rowHeight = ROWS_HEIGHT[this.cols];
categoria: string | undefined;
constructor(){
}
ngOnInit(): void {
}
onColumnsCountChange(numCols: number): void {
this.cols = numCols;
this.rowHeight=ROWS_HEIGHT[this.cols];
}
onShowCategoria(novaCategoria: string): void {
this.categoria = novaCategoria;
}
}
app-component.ts
import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { HeaderComponent } from './components/header/header.component';
import { HomeComponent } from './pages/home/home.component';
import { CarrinhoComponent } from './pages/carrinho/carrinho.component';
@Component({
selector: 'app-root',
standalone: true,
imports: [HomeComponent, HeaderComponent, CarrinhoComponent, RouterOutlet],
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
title = 'loja';
}
app-component.html
<app-header></app-header>
<router-outlet></router-outlet>
<app-home></app-home>
header-component.html (with a button using routerLink for carrinho (cart) route)
<mat-toolbar class="mat-toolbar-custom max-w-7x1-mx-auto border-x justify-between">
<a routerLink="home">Conheça a Loja</a>
<button mat-icon-button [matMenuTriggerFor]="menu">
<mat-icon
[matBadge] = "1"
[style.color]="'rgb(22, 99, 115)'"
>shopping_cart</mat-icon>
</button>
<mat-menu #menu="matMenu">
<div class="p-3 divide-y divide-solid">
<div class="pb-3 flex justify-between">
<span class="mr-16">1 items</span>
<br>
<a routerLink="carrinho">Consultar Carrinho</a>
</div>
<div class="p-4">
<div class="flex justify-between font-light mb2">
Keyboard x1
<span class="font-bold">{{ '150' | currency: 'BRL' }}</span>
</div>
<div class="flex justify-between font-light mb2">
Keyboard x1
<span class="font-bold">{{ '150' | currency: 'BRL' }}</span>
</div>
<div class ="flex justify-between py-3 font-light">
Total:
<span class="font-bold">{{ '300' | currency: 'BRL'}}</span>
</div>
<div class="pt-3 flex justify-between">
<button class="bg-text-white-rounded-full w-10 h-10">
<mat-icon>remove_shopping_cart</mat-icon>
</button>
<button routerLink="carrinho" class="bg-text-white-rounded-full w-10 h-10">
<mat-icon>remove_shopping_cart</mat-icon>
</button>
</div>
</div>
</div>
</mat-menu>
</mat-toolbar>
carrinho.component.html
<p>carrinho works!</p>
I expected to actually redirect to localhost:4200/home (showing what's inside the home-component) and localhost:4200/carrinho (showing what's inside the carrinho-component, which's 'carrinho works' just for test purposes).
Update2: I added the routes also in the app-routes.ts and it seems like /carrinho is now working, but is loading the components of the home page as well, and not only the ones from carrinho route, so not displaying correctly. Same for the home page.. (this page was right before like in picture 2 without the 'carrinho works')
https://i.sstatic.net/4jFcW.png
https://i.sstatic.net/VLtoZ.png
https://i.sstatic.net/rGDKx.png
Solved: Finally solved the problem with the route carrinho loading components from other routes using the changeDetectionStrategy Alpine used in his answer!
You need to change the app.component.html:
<app-header></app-header>
<router-outlet></router-outlet>
<app-home></app-home>
To
<app-header></app-header>
<router-outlet></router-outlet>
The header contains the routerLink of the component, so it's displayed with router-outlet.
This route config creates a static link to the route:
// app-header
<a routerLink="/home">Home component </a>
<a routerLink="/carrinho">Carrinho component</a>
// route configuration
const routes: Routes = [
{
path: 'home',
component: HomeComponent,
},
{
path: 'carrinho',
component: CarrinhoComponent,
},
{ path: '', redirectTo: '/home', pathMatch: 'full' },
];
Note: