2

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?

RafaelTSCS
  • 1,234
  • 2
  • 15
  • 36

3 Answers3

6

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...

Ashish Ranjan
  • 12,760
  • 5
  • 27
  • 51
5

You can try like this : [routerLink]="['/user/', 1, '/edit']"

More generally, you can put your id parameter like this :

[routerLink]="['/user', <your param 1>, 'edit', <your param 2>]"

Sony
  • 7,136
  • 5
  • 45
  • 68
Johan Rin
  • 1,900
  • 2
  • 20
  • 42
0

In component, you can do this with Router:

Imports:

import { ActivatedRoute, Router } from '@angular/router';

constructor(private router: Router){
}

navigate(id){
this.router.navigate(['/user/'+id+'/edit']);
}
Prashant Pimpale
  • 10,349
  • 9
  • 44
  • 84