Custom encoding for urls using Angular 2 Router (using a + sign in place of a space)

I was able to find a solution to my problem. You can make own custom url serializer by implementing the UrlSerializer class.

Custom Url Serializer

Create a custom url serializer like this:

class CustomUrlSerializer implements UrlSerializer {
    parse(url: string): UrlTree {
        // Custom code here
    }

    serialize(tree: UrlTree): string {
        // Custom code here
    }
}

Then, you just need to provide the CustomUrlSerializer in place of the UrlSerializer, which you can place in the AppModule providers array after importing both serializers.

providers: [
    { provide: UrlSerializer, useClass: CustomUrlSerializer },
    ...
]

Now, when you call router.navigate or router.navigateByUrl, it will use your custom serializer for parsing and serializing.

Using + signs as spaces

To parse + signs as spaces:

parse(url: string): UrlTree {
    // Change plus signs to encoded spaces
    url = url.replace(/\+/g, '%20');
    // Use the default serializer that you can import to just do the 
    // default parsing now that you have fixed the url.
    return this.defaultUrlSerializer.parse(url)  
}

And for serializing:

serialize(tree: UrlTree): string {
    // Use the default serializer to create a url and replace any spaces with + signs
    return this.defaultSerializer.serialize(tree).replace(/%20/g, '+');
}

DefaultUrlSerializer


I ran into an issue specifying the custom provider. There was apparently a circular dependency when compiling with the --prod flag causing an error with the text: useClass cannot by null. This is how I worked around that error:

In AppModule, define the following:

const customUrlSerializer = new CustomUrlSerializer();
const CustomUrlSerializerProvider = {
    provide: UrlSerializer,
    useValue: customUrlSerializer
};

Then in the providers array, add the provider you specified above.

...
providers: [CustomUrlSerializerProvider]
...