Search code examples
angularurl-parametersangular-routerangular7

Angular route: URL like /my/:parameter/path


I am trying to setup a URL like 'user/:id/edit', but when I use [routerLink]="['user/:id/edit', 1]" it generates /user/:id/edit/1.

If I use [routerLink]="['user/:id/edit', {id: 1}]" it generates /user/:id/edit;id=1

Is there a way of getting the output as /users/1/edit without using String interpolation?


Solution

  • I believe this question of yours is an extension of another question of yours. Here your requirement would be to get an array which is correctly translated with respect to the parameters you want to pass. With this what I mean is:

    Let's say we have a route configuration as

    const routes: Routes = [
      {path: "first/:id1/second/:id2", component: HelloComponent}
    ]
    

    When using this in a [routerLink], you will want to have the input property to be like: ['first', 'param1', 'second', 'param2']. Not as: ['first/param1/second/param2']. If you do this then even though you will be routed to the desired path, your ActivatedRoute will not have any params inside them(in case you need to grab the params from the router).

    Now your task would be to create such array for the routerLinks.

    Let's create a Pipe which does this and is performance efficient.

    import { Pipe, PipeTransform } from '@angular/core';
    
    @Pipe({
        name: 'routerArray'
    })
    export class RouterArrayPipe implements PipeTransform {
        transform(routerPath: string, params: string | number[]): string | number[] {
            // regex to find all the param placeholders in the route path
            let regex = /(\/:[a-zA-Z0-9]*\/?)/g;
            // will be returned as output
            let routerArray = [];
            // contains the output of regex.exec()
            let match = null;
            // index to retrieve the parameters for route from params array
            let paramIndex = 0;
            while (match = regex.exec(routerPath)) {
                // push the first part of the path with param placeholder
                routerArray.push(routerPath.substring(0, match.index))
                // push the param at paramIndex
                routerArray.push(params[paramIndex++]);
                // remove the contents from routerPath which are processed
                routerPath = routerPath.substring(regex.lastIndex);
                // regex is stateful, reset the lastIndex coz routerPath was changed.
                regex.lastIndex = 0;
            }
            // if the recieved route path didn't accept any argumets
            if (routerArray.length === 0) {
                routerArray.push(routerPath)
            }
            return routerArray
        }
    }
    

    Now you can use the pipe like:

    <button [routerLink]="'first/:id1/second/:id2' | routerArray: ['1', '2']">Click to Navigate</button>
    

    See an Example here...