Search code examples
angularangular-routingwebshop

How to implement angular routing for product categories?


I’m creating a webshop in angular with firebase. I don’t want to create a different component for each category. Example route: /products/tables it should list out all the tables. 2nd example: /products/chairs it should list out all the chairs. When a user clicks on a chair the route should be: /products/chairs/1234 where 1234 is the product id. Is this possibble without defining every single category as a route?


Solution

  • app.routing.ts:

    import { NgModule } from '@angular/core';
    import { RouterModule, Routes } from '@angular/router';
    import { CategoryComponent } from './products/category/category.component';
    import { ProductComponent } from './products/category/product/product.component';
    import { ProductsComponent } from './products/products.component';
    const routes: Routes = [
        { path: '', pathMatch: 'full', component: ProductsComponent },
        { path: 'products/:category', component: CategoryComponent },
        { path: 'products/:category/:id', component: ProductComponent },
    ];
    @NgModule({
        imports: [RouterModule.forRoot(routes)],
        exports: [RouterModule],
    })
    export class AppRoutingModule {}
    

    app.component.html:

    <router-outlet></router-outlet>
    

    products.components.ts:

    import { Component, OnInit } from '@angular/core';
    import { ProductsService } from '../products.service';
    @Component({
        selector: 'app-products',
        template: `
            <h1>Products:</h1>
            <ul>
                <li *ngFor="let category of categories">
                    <a routerLink="{{ 'products/' + category }}">
                        <h1>
                            {{ category }}
                        </h1>
                    </a>
                </li>
            </ul>
        `,
        styleUrls: ['./products.component.css'],
    })
    export class ProductsComponent implements OnInit {
        categories: string[] = [];
        constructor(private productsService: ProductsService) {}
        ngOnInit(): void {
            this.categories = this.productsService.getCategoryNames();
        }
    }
    

    category.component.ts:

    import { Component, OnInit } from '@angular/core';
    import { ActivatedRoute, Params } from '@angular/router';
    import { ProductsService } from 'src/app/products.service';
    @Component({
        selector: 'app-category',
        template: `
            <h1>Products in {{ category }} category:</h1>
            <ul>
                <li *ngFor="let product of products; index as i">
                    <a routerLink="{{ i }}">
                        <h2>
                            {{ product }}
                        </h2>
                    </a>
                </li>
            </ul>
        `,
        styleUrls: ['./category.component.css'],
    })
    export class CategoryComponent implements OnInit {
        products: string[] = [];
        category = '';
        constructor(
            private route: ActivatedRoute,
            private productsService: ProductsService
        ) {}
        ngOnInit(): void {
            this.route.params.subscribe((params: Params) => {
                this.category = params['category'];
                this.products = this.productsService.getCategoryItems(
                    this.category
                );
            });
        }
    }
    

    product.component.ts:

    import { Component, OnInit } from '@angular/core';
    import { ActivatedRoute, Params } from '@angular/router';
    import { ProductsService } from 'src/app/products.service';
    @Component({
        selector: 'app-product',
        template: `
            <h3>
                {{ product }}
            </h3>
        `,
        styleUrls: ['./product.component.css'],
    })
    export class ProductComponent implements OnInit {
        product = '';
        constructor(
            private route: ActivatedRoute,
            private productsService: ProductsService
        ) {}
        ngOnInit(): void {
            this.route.params.subscribe((params: Params) => {
                const category: string = params['category'];
                const id: number = params['id'];
                this.product = this.productsService.getProduct(category, id);
            });
        }
    }
    

    app.module.ts:

    import { NgModule } from '@angular/core';
    import { BrowserModule } from '@angular/platform-browser';
    
    import { AppRoutingModule } from './app-routing.module';
    import { AppComponent } from './app.component';
    import { ProductsService } from './products.service';
    import { CategoryComponent } from './products/category/category.component';
    import { ProductComponent } from './products/category/product/product.component';
    import { ProductsComponent } from './products/products.component';
    @NgModule({
        declarations: [
            AppComponent,
            ProductsComponent,
            CategoryComponent,
            ProductComponent,
        ],
        imports: [BrowserModule, AppRoutingModule],
        providers: [ProductsService],
        bootstrap: [AppComponent],
    })
    export class AppModule {}
    

    products.service.ts:

    export class ProductsService {
        products: any = {
            tables: ['table1', 'table2', 'table3'],
            chairs: ['chair1', 'chair2', 'chair3', 'chair4'],
        };
        getProduct(category: string, id: number) {
            return this.products[category][id];
        }
        getCategoryItems(category: string) {
            return this.products[category];
        }
        getCategoryNames() {
            return Object.keys(this.products);
        }
    }