3

I am using angular 2.0, specifically the routing features for the purposes of this question. The way I have set up my routing looks like this.

const routes: Routes = [
    { path : ':filePath', component: ParentDisplayComponent,
        children : [
            { path : 'metadata', component: MetadataDisplayComponent },
            { path : 'data', component : DataDisplayComponent } 
        ]
    }
];

So as you can see, a url of mine might end up looking like this.

<host>:<port>/#/<file path>/metadata

However, because I am making a file browser of sorts, my "file paths" (the initial parameter) look like this.

/foo/bar/baz

In order to make this work, I've had to escape the slashes, so now my urls end up looking like this

<host>:<port>/#/%252ffoo%252fbar%252fbaz/metadata

I know that this is more or less "fine", but I seriously hate the look of this, and it isn't very user friendly, as far as manually entering the url. Does anyone have any suggestions on how to make my urls more user friendly? I kind of do need a parent level component that keeps track of the chosen file, which is why I didn't do something like this.

<host>:<port>/#/metadata?path=/foo/bar/baz

The reason for this is that I want my app to have a "browser" (similar to windows explorer) on the left side of the screen at all times, with a swappable component in the middle of the screen. Picture something like this.

 ___________________________
|___________________________|
|       |
|file a |  ____________________
|file b |  |swappable component|
|file c |  ---------------------
|etc... | 

That's probably enough rambling. Does anyone have any ideas as far as making my urls nicer, considering that I must have parameters containing slashes?

isherwood
  • 58,414
  • 16
  • 114
  • 157
Zack
  • 13,454
  • 24
  • 75
  • 113
  • 1
    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:42

2 Answers2

3

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 (%2). I was passing Query as lang=en-us,en-uk where it was getting converted to lang=en-us%2en-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(/%2/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
1

You can't prevent slashes from being encoded. I'd use matrix parameters which look cleaner.

http://page.com/home/example;a=foo;b=bar;c=baz/something

You can use Router's navigate method to use them

this.router.navigate(['/home', '/example', { a: 'foo', b: 'bar', c: 'baz' }, '/something']);

To get current params, use ActivatedRoute's params property to which you can subscribe.

Michał Pietraszko
  • 5,666
  • 3
  • 21
  • 27
  • each foo, bar, and baz does not correspond to an optional parameter though... rather.... "/foo/bar/baz" refers to one REQUIRED parameter. – Zack Jan 10 '17 at 22:01
  • This is the only thing that can look clean. Angular's router isn't the perfect solution in your case and creating custom one should help you solve the problem. – Michał Pietraszko Jan 10 '17 at 22:08
  • I'm giving this a try... a url like this /metadata?path=/foo/bar/baz, grab the path from within the metadata component, load what I need from the backend, and then broadcast that up to the parent. If I do this, then I need to make sure that I am not regrabbing the data each time I change components... only when the path query param changes.... ahh... I wish we weren't using slashes for our delimiters. Oh well. Thanks anyways! – Zack Jan 10 '17 at 22:13