Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove parenthesis in URL when using child/ auxiliary routes (named routers) in Angular2?

I am using named routers in my application to implement routing in one of the shared modules.

This is what configuration looks like in AppRoutingModule (root):

    const routes: Routes = [
  {
    path: '',
    children: [
      {
        path: 'home',
        component: HomeDetailsComponent,
      },
      {
        path: 'call',
        component: CallDetailsComponent
      },
    ]
  }
];

Then, when user navigates to first path, that is '/home', then there is a separate routing module for this module which has the following configuration:

const curriculumRoutes: Routes = [ 
  {
    path: 'home',
    component: HomeDetailsComponent,
    children: [
      {
        path: ':id',
        component: RoomDetailsComponent,
        outlet: 'chapter',
      }
    ]
  },
];

For first root configuration, I am using primary outlet to render the components and for second configuration, I am using named router 'chapter'. The URL which I am getting from primary router outlet is following:

http://localhost:3000/#/home

But with further named router outlet, it is like this:

http://localhost:3000/#/home/(chapter:2)

How to have an URL like this for named router outlets as well:

    http://localhost:3000/#/home/chapter/2
like image 423
Jayant Pareek Avatar asked Jan 26 '17 10:01

Jayant Pareek


2 Answers

I made a solution, hope it can help others.

The solution override of the UrlSerializer.

In this example we translate to aux like this:

parse: /instruments/ukulele => /instruments/(instruments:ukulele)

serialize: /instruments/(instruments:ukulele) => /instruments/ukulele

So that the end user only sees the pretty url:

/instruments/ukulele

The implementation of the UrlSerializer:

//app.rounting.ts
const routes: Routes = [
    /*...*/
    {
        path: 'instruments', component: InstrumentsComponent,
        children: [
            {
                path: 'ukulele',
                component: UkuleleComponent,
                outlet: 'instruments'
            }
        ]
    }
];

//app.module.ts
@NgModule({
  /*...*/
    declarations: [
    /*...*/
        InstrumentsComponent,
        UkuleleComponent
    ],
  /*...*/
    providers: [
        {
            provide: UrlSerializer,
            useClass: StandardUrlSerializer
        }
    ],
  /*...*/
})


//app.contants.ts
export let appContants = {
    outlets: ['instruments']
};


// StandardUrlSerializer.ts
import { DefaultUrlSerializer, UrlSerializer, UrlTree } from '@angular/router';
import { appContants } from '../app.constants';

export class StandardUrlSerializer implements UrlSerializer {
    private _defaultUrlSerializer: DefaultUrlSerializer = new DefaultUrlSerializer();

    parse(url: string): UrlTree {
        appContants.outlets.forEach(outletName => {
            const reg = new RegExp('/(' + outletName + ')/([^\/]*)');
            url = url.replace(reg, '$1/($1:$2)' );
        });
        return this._defaultUrlSerializer.parse(url);
    }

    serialize(tree: UrlTree): string {
        let url = this._defaultUrlSerializer.serialize(tree);
        appContants.outlets.forEach(outletName => {
            const reg = new RegExp('\\(' + outletName + ':([^\/]*)\\)');
            url = url.replace(reg, '$1');
        });
        return url;
    }
}
<!-- app.component.html -->
<!-- ... -->
<a routerLinkActive="active" routerLink="/instruments">Instruments</a>
<router-outlet></router-outlet>
<!-- ... -->

<!-- instruments.component.html -->
<!-- ... sub menu etc.. -->
<a class="nav-item nav-link" routerLinkActive="active" [routerLink]="[{ outlets: { instruments: ['ukulele'] } }]">Ukulele</a>
<router-outlet name="instruments"></router-outlet>
<!-- ... -->

<!-- ukulele.component.html -->
<p>ukulele works!</p>
like image 172
Alf Nielsen Avatar answered Oct 20 '22 18:10

Alf Nielsen


You can provide a custom URL serializer

https://angular.io/docs/ts/latest/api/router/index/UrlSerializer-class.html

like image 4
Günter Zöchbauer Avatar answered Oct 20 '22 18:10

Günter Zöchbauer