0

I need to customize how my URLs are encoded when calling the navigate method on the router.

I know I need to implement my own version of UrlSerializer and write a custom serialize method. My problem is really that the only method I wish to change is the encode method in url_tree.

export function encode(s) {
    return encodeURIComponent(s);
}

https://github.com/angular/angular/blob/master/modules/@angular/router/src/url_tree.ts#L344

In order to do this I need to copy + paste all the following methods from url_tree into my CustomSerializer because they are not exported:

serialize

serializeQueryParams

Pair

pairs

serializeSegment

encode

I've looked at this answer but it doesn't quite solve my problem as I want all the default behaviour except for the encode method.

Am I missing something here or is there a better way to solve this issue?

Community
  • 1
  • 1
garethdn
  • 12,022
  • 11
  • 49
  • 83
  • Have you considered extending an existing implementation? What behaviour precisely are you trying to change, and for what reason? – jonrsharpe Nov 10 '16 at 17:13
  • @jonrsharpe I would like to handle param encoding myself. My URL structure should resemble something `qs=test,my%20test,this%2Cthat`. I split the qs param by `,` to get the values. Angular's default encoding, however, encodes the commas – garethdn Nov 10 '16 at 17:18
  • Possible duplicate of [angular 2 disable url encoding](http://stackoverflow.com/questions/41476193/angular-2-disable-url-encoding) – jigar gala Feb 09 '17 at 16:28

1 Answers1

6

Angular2 by default uses encodeURIComponent() to encode queryParams in URL, you can avoid it by writing custom URL serializer and override default functionality.

In my case, I wanted to avoid Angular2 to avoid replacing comma(,) by (%2C). I was passing Query as lang=en-us,en-uk where it was getting converted to lang=en-us%2Cen-uk.

Here how I worked it out:

CustomUrlSerializer.ts

import {UrlSerializer, UrlTree, DefaultUrlSerializer} from '@angular/router';

export class CustomUrlSerializer implements UrlSerializer {
    parse(url: any): UrlTree {
        let dus = new DefaultUrlSerializer();
        return dus.parse(url);
    }

    serialize(tree: UrlTree): any {
        let dus = new DefaultUrlSerializer(),
        path = dus.serialize(tree);
        // use your regex to replace as per your requirement.
        return path.replace(/%2C/g,',');
      }
   }

Add below line to your main appModule.ts

import {UrlSerializer} from '@angular/router';
import {CustomUrlSerializer} from './CustomUrlSerializer';

@NgModule({
    providers: [{ provide: UrlSerializer, useClass: CustomUrlSerializer }]
})

This won't break your default functionality and take cares of URL as per your need.

jigar gala
  • 1,600
  • 12
  • 20
  • In my case, the ! is not being replaced with %21 and is effectively breaking my code (and redirects me back to the root navigation path). Do you recommend using your method or submitting a bug request to the Angular team? – aspergillusOryzae Aug 30 '17 at 18:21
  • you can use this method and handle the URL encoding, try changing regex as per your requirement and let me know how it behaves. – jigar gala Aug 30 '17 at 18:24
  • Hi Am trying to change my '/' to '-' . Means Slash to Hyphen am trying for Seo friendly URL structure. While routing its perfect. But while reload the page. Component conflict is coming as an error. Any Idea.??? – Abijith Ajayan Feb 06 '20 at 09:43