0


I have been working on Angular project with routing , so lets consider a route like this below.

  {
    path : 'preview/:Id',
    loadChildren : () => import('./path/preview/preview.module').then( m => m.PreviewModule),
  }

So this route could be having alphanumeric values like (a-zA-Z0-9) and also special character like / , hash value produced by crypto.js like below.

preview/QQZnNw+VjBg/cAXvy6nxdiQ==

so In this above route param Id will have some value like this QQZnNw+VjBg/cAXvy6nxdiQ== , that is what am trying to achieve.

Error : But unfortunately am getting error stating unrecognised route because , this above value has "/" in its route.

Previously what i have tried is that i have tried adding regex like this /:Id(/[\\S]+/g) to the route param so that it could accept this route ,

  {
    path : 'preview/:Id(/[\\S]+/g)',
    loadChildren : () => import('./path/preview/preview.module').then( m => m.PreviewModule),
  }

Please , can anyone help me find a way.

guru_007
  • 473
  • 4
  • 16

2 Answers2

1

You can use a UrlMatcher.

function slashMatcher(path: string, param: string): UrlMatcher {
  return (
    segments: UrlSegment[],
    group: UrlSegmentGroup,
    route: Route
  ): UrlMatchResult => {
    const { length } = segments;
    const firstSegment = segments[0];
    if (firstSegment.path === path && length >= 2) { // firstSegment.path == preview
      const paramSegments = segments.slice(1);
      const paramPaths = paramSegments.map(segment => segment.path); // ["QQZnNw+VjBg", "cAXvy6nxdiQ=="]
      const mergedParam = paramPaths.join("/"); // QQZnNw+VjBg/cAXvy6nxdiQ==
      const idSegment: UrlSegment = new UrlSegment(mergedParam, { [param]: mergedParam });
      return { consumed: segments, posParams: { [param]: idSegment } };
    }
    return null;
  };
}

const routes: Routes = [
  { 
    matcher: slashMatcher('preview', 'Id'), 
    loadChildren : () => import('./path/preview/preview.module').then( m => m.PreviewModule),
  },
];

// In component
const id$ = this.route.paramMap.pipe(map(params => params.get('Id')));
frido
  • 13,065
  • 5
  • 42
  • 56
0

I found a way around thanks to this answer.

I have created two utility functions to replace "/" with some hashcode when encrypting and while decrypting that hashcode back to "/".

 convertSpecial = (text: string) => {
    const ciphertext = this.encrypt(text);
    return ciphertext.replace(/\+/g,'p1L2u3S').replace(/\//g,'s1L2a3S4h').replace(/=/g,'e1Q2u3A4l');
  }

  unconvertSpecial = (ciphertext: string) => {
    ciphertext = ciphertext.toString().replace(/p1L2u3S/g, '+' ).replace(/s1L2a3S4h/g, '/').replace(/e1Q2u3A4l/g, '=');
    const text = this.decrypt(ciphertext);
    return text;
  }

so while redirecting ,

<a href="#" [routerLink]="['/preview', convertSpecial(item?._id)]" > </a>

on Mounting the component ,

ngOnit()
{
this.Id = this.unconvertSpecial(this.Id);
}
guru_007
  • 473
  • 4
  • 16