angularangular-router

Config routing with a constant string with a param in angular


I want to config routing like this : hotel-123, hotel-456,... with 'hotel' is a constant string and 123, 456 is param 'code'.

This is my app.routes.ts :

import { Routes } from '@angular/router';
    
export const routes: Routes = [
    {
        path: 'hotel-:code',
        loadComponent: () => import('../pages/hotel/hotel.component').then(m => m.HotelComponent)
    }
];

..but it's not work. I got error 'Error: Uncaught (in promise): Error: NG04002: Cannot match any routes. URL Segment: 'hotel-123'' when trying access this path.

I spent hours for searching this but there aren't any clue. Is this possilble in Angular ? Do you have any solution for this ?

P/s : I use Angular 17.3.6

Thanks for reading !


Solution

  • As @JSON Derulo 's suggest, i found the solution after many tries.

    In app.routes.ts :

    import { Routes, UrlSegment } from '@angular/router';
    
    export const routes: Routes = [
        {
            matcher : (url) => {
                if (url.length === 1 && url[0].path.match(/^hotel-[\w-]+$/gm)) {
                    return {
                        consumed: url,
                        posParams: {
                            code: new UrlSegment(url[0].path.substring(6), {}) // with my example '/hotel-123', code value will be '123'
                        }
                    };
                }
                
                return null;
            },
            loadComponent: () => import('./pages/hotel/hotel.component').then(c => c.HotelComponent)
        },
    ];
    

    In hotel.component.ts :

    import { Component } from '@angular/core';
    import { ActivatedRoute} from '@angular/router';
    
    
    @Component({
      selector: 'my-hotel',
      standalone: true,
      imports: [],
      templateUrl: './hotel.component.html',
      styleUrl: './hotel.component.scss'
    })
    export class HotelComponent {
    
      code : string;
    
      constructor(private _route: ActivatedRoute) {
        this._route.paramMap.subscribe(paramsMap => {
          this.code = paramsMap.get('code') ?? '';
    
          // do something ...
        })
      }
    }
    

    Also, @Eliseo's comment is helpful too ! Angular Matcher document